]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
issue27186 -- initial docs, tests, and python version of os.fspath
authorEthan Furman <ethan@stoneleaf.us>
Thu, 2 Jun 2016 22:06:09 +0000 (15:06 -0700)
committerEthan Furman <ethan@stoneleaf.us>
Thu, 2 Jun 2016 22:06:09 +0000 (15:06 -0700)
Doc/library/os.rst
Lib/os.py
Lib/test/test_os.py

index 1b0ad17b8d31783176322a6ab070125279dcc40f..4ed01dd3de0dad14c6e03315a77c0248e66f3edd 100644 (file)
@@ -186,6 +186,15 @@ process and user.
    .. versionadded:: 3.2
 
 
+.. function:: fspath(path)
+
+   Return the string representation of the path.
+
+   If :class:`str` or :class:`bytes` is passed in, it is returned unchanged;
+   otherwise, the result of calling ``type(path).__fspath__`` is returned, or an
+   exception is raised.
+
+
 .. function:: getenv(key, default=None)
 
    Return the value of the environment variable *key* if it exists, or
index 90646a055366e464f458985a6e3041901b5bb117..edd61ab8f8036c5d1dbb782409626f398093dc56 100644 (file)
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -1097,3 +1097,24 @@ def fdopen(fd, *args, **kwargs):
         raise TypeError("invalid fd type (%s, expected integer)" % type(fd))
     import io
     return io.open(fd, *args, **kwargs)
+
+# Supply os.fspath()
+def fspath(path):
+    """Return the string representation of the path.
+
+    If str or bytes is passed in, it is returned unchanged.
+    """
+    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:
+        return path_type.__fspath__(path)
+    except AttributeError:
+        if hasattr(path_type, '__fspath__'):
+            raise
+
+        raise TypeError("expected str, bytes or os.PathLike object, not "
+                        + path_type.__name__)
index 01404ff4f63a71331d3a719c2845b9d957bd5993..f52de2876843a0060e0fed7f30b2cb2d7dfbedc4 100644 (file)
@@ -3095,5 +3095,26 @@ class TestScandir(unittest.TestCase):
             del iterator
 
 
+class TestPEP519(unittest.TestCase):
+    "os.fspath()"
+
+    def test_return_bytes(self):
+        for b in b'hello', b'goodbye', b'some/path/and/file':
+            self.assertEqual(b, os.fspath(b))
+
+    def test_return_string(self):
+        for s in 'hello', 'goodbye', 'some/path/and/file':
+            self.assertEqual(s, os.fspath(s))
+
+    def test_garbage_in_exception_out(self):
+        vapor = type('blah', (), {})
+        for o in int, type, os, vapor():
+            self.assertRaises(TypeError, os.fspath, o)
+
+    def test_argument_required(self):
+        with self.assertRaises(TypeError):
+            os.fspath()
+
+
 if __name__ == "__main__":
     unittest.main()