From b54354860f865f4acb175bda9bbb94fc26def6e3 Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Sat, 11 May 2019 18:06:06 +0300 Subject: [PATCH 1/2] Move fspath to _os --- Lib/os.py | 31 ------------------------------- vm/src/stdlib/os.rs | 17 ++++++++++++++++- 2 files changed, 16 insertions(+), 32 deletions(-) diff --git a/Lib/os.py b/Lib/os.py index c768946c52..cb49481dff 100644 --- a/Lib/os.py +++ b/Lib/os.py @@ -133,34 +133,3 @@ def getenv(key, default=None): The optional second argument can specify an alternate default. key, default and the result are str.""" return environ.get(key, default) - - -def fspath(path): - """Return the path representation of a path-like object. - - If str or bytes is passed in, it is returned unchanged. Otherwise the - os.PathLike interface is used to get the path representation. If the - path representation is not str or bytes, TypeError is raised. If the - provided path is not str, bytes, or os.PathLike, TypeError is raised. - """ - if isinstance(path, (str, bytes)): - return path - - # Work from the object's type to match method resolution of other magic - # methods. - path_type = type(path) - try: - path_repr = path_type.__fspath__(path) - except AttributeError: - if hasattr(path_type, '__fspath__'): - raise - else: - raise TypeError("expected str, bytes or os.PathLike object, " - "not " + path_type.__name__) - if isinstance(path_repr, (str, bytes)): - return path_repr - else: - raise TypeError("expected {}.__fspath__() to return str or bytes, " - "not {}".format(path_type.__name__, - type(path_repr).__name__)) - diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index c01b5aaac2..a69a97cc24 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -14,9 +14,10 @@ use crate::obj::objint::PyIntRef; use crate::obj::objiter; use crate::obj::objstr; use crate::obj::objstr::PyStringRef; +use crate::obj::objtype; use crate::obj::objtype::PyClassRef; use crate::pyobject::{ - ItemProtocol, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, TryIntoRef, + ItemProtocol, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, TryIntoRef, TypeProtocol, }; use crate::vm::VirtualMachine; @@ -492,6 +493,19 @@ fn os_chdir(path: PyStringRef, vm: &VirtualMachine) -> PyResult<()> { env::set_current_dir(&path.value).map_err(|s| vm.new_os_error(s.to_string())) } +fn os_fspath(path: PyObjectRef, vm: &VirtualMachine) -> PyResult { + if objtype::issubclass(&path.class(), &vm.ctx.str_type()) + || objtype::issubclass(&path.class(), &vm.ctx.bytes_type()) + { + Ok(path) + } else { + Err(vm.new_type_error(format!( + "expected str or bytes object, not {}", + path.class() + ))) + } +} + pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { let ctx = &vm.ctx; @@ -549,6 +563,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { "symlink" => ctx.new_rustfunc(os_symlink), "getcwd" => ctx.new_rustfunc(os_getcwd), "chdir" => ctx.new_rustfunc(os_chdir), + "fspath" => ctx.new_rustfunc(os_fspath), "O_RDONLY" => ctx.new_int(0), "O_WRONLY" => ctx.new_int(1), "O_RDWR" => ctx.new_int(2), From d96d04f0fde2bb4b567bac75d70ebf0c53cf8069 Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Sat, 11 May 2019 18:08:47 +0300 Subject: [PATCH 2/2] Add os.fspath tests --- tests/snippets/stdlib_os.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/snippets/stdlib_os.py b/tests/snippets/stdlib_os.py index 39d5e7bdcb..32cb7d4a9b 100644 --- a/tests/snippets/stdlib_os.py +++ b/tests/snippets/stdlib_os.py @@ -49,6 +49,10 @@ assert os.altsep == None assert os.pathsep == ":" +assert os.fspath("Testing") == "Testing" +assert os.fspath(b"Testing") == b"Testing" +assert_raises(TypeError, lambda: os.fspath([1,2,3])) + class TestWithTempDir(): def __enter__(self): if os.name == "nt":