Author: Mariano Anaya <marianoan...@gmail.com>
Branch: py3.6
Changeset: r91873:5041f795bfb2
Date: 2017-07-15 12:34 +0200
http://bitbucket.org/pypy/pypy/changeset/5041f795bfb2/

Log:    Add posix.fspath

        Add fspath to posix, so it's available in os.fspath.

        New feature added in CPython 3.6:
        https://docs.python.org/3/library/os.html#os.fspath

diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py
--- a/pypy/module/posix/__init__.py
+++ b/pypy/module/posix/__init__.py
@@ -83,6 +83,7 @@
         'scandir': 'interp_scandir.scandir',
         'get_inheritable': 'interp_posix.get_inheritable',
         'set_inheritable': 'interp_posix.set_inheritable',
+        'fspath': 'interp_posix.fspath',
     }
 
     if hasattr(os, 'chown'):
@@ -228,7 +229,7 @@
         'POSIX_FADV_RANDOM', 'POSIX_FADV_NOREUSE', 'POSIX_FADV_DONTNEED']:
             assert getattr(rposix, _name) is not None, "missing %r" % (_name,)
             interpleveldefs[_name] = 'space.wrap(%d)' % getattr(rposix, _name)
-    
+
     if hasattr(rposix, 'sched_get_priority_max'):
         interpleveldefs['sched_get_priority_max'] = 
'interp_posix.sched_get_priority_max'
         interpleveldefs['sched_get_priority_min'] = 
'interp_posix.sched_get_priority_min'
diff --git a/pypy/module/posix/interp_posix.py 
b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -2437,8 +2437,8 @@
 
 @unwrap_spec(policy=int)
 def sched_get_priority_max(space, policy):
-    """returns the maximum priority value that 
-    can be used with the scheduling algorithm 
+    """returns the maximum priority value that
+    can be used with the scheduling algorithm
     identified by policy
     """
     while True:
@@ -2452,7 +2452,7 @@
 @unwrap_spec(policy=int)
 def sched_get_priority_min(space, policy):
     """returns the minimum priority value that
-     can be used with the scheduling algorithm 
+     can be used with the scheduling algorithm
      identified by policy
     """
     while True:
@@ -2462,3 +2462,36 @@
             wrap_oserror(space, e, eintr_retry=True)
         else:
            return space.newint(s)
+
+
+def fspath(space, w_path):
+    """
+    Return the file system path representation of the object.
+
+    If the object is str or bytes, then allow it to pass through as-is. If the
+    object defines __fspath__(), then return the result of that method. All 
other
+    types raise a TypeError.
+    """
+    if (space.isinstance_w(w_path, space.w_text) or
+        space.isinstance_w(w_path, space.w_bytes)):
+        return w_path
+
+    w_fspath_method = space.lookup(w_path, '__fspath__')
+    if w_fspath_method is None:
+        raise oefmt(
+            space.w_TypeError,
+            'expected str, bytes or os.PathLike object, not %T',
+            w_path
+        )
+
+    w_result = space.get_and_call_function(w_fspath_method, w_path)
+    if (space.isinstance_w(w_result, space.w_text) or
+        space.isinstance_w(w_result, space.w_bytes)):
+        return w_result
+
+    raise oefmt(
+        space.w_TypeError,
+        'expected %T.__fspath__() to return str or bytes, not %T',
+        w_path,
+        w_result
+    )
diff --git a/pypy/module/posix/test/test_posix2.py 
b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -964,7 +964,7 @@
             assert posix.sched_get_priority_min(posix.SCHED_OTHER) != -1
             if getattr(posix, 'SCHED_BATCH', None):
                 assert posix.sched_get_priority_min(posix.SCHED_BATCH) != -1
-            
+
     if hasattr(rposix, 'sched_get_priority_min'):
         def test_os_sched_priority_max_greater_than_min(self):
             posix, os = self.posix, self.os
@@ -1411,6 +1411,32 @@
         e = raises(OSError, self.posix.symlink, 'bok', '/nonexistentdir/boz')
         assert str(e.value).endswith(": 'bok' -> '/nonexistentdir/boz'")
 
+    def test_os_fspath(self):
+        assert hasattr(self.posix, 'fspath')
+        raises(TypeError, self.posix.fspath, None)
+        e = raises(TypeError, self.posix.fspath, 42)
+        assert str(e.value).endswith('int')
+        string = 'string'
+        assert self.posix.fspath(string) == string
+        assert self.posix.fspath(b'bytes') == b'bytes'
+        class Sample:
+            def __fspath__(self):
+                return 'sample'
+
+        assert self.posix.fspath(Sample()) == 'sample'
+
+        class BSample:
+            def __fspath__(self):
+                return b'binary sample'
+
+        assert self.posix.fspath(BSample()) == b'binary sample'
+
+        class WrongSample:
+            def __fspath__(self):
+                return 4
+
+        raises(TypeError, self.posix.fspath, WrongSample())
+
 
 class AppTestEnvironment(object):
     def setup_class(cls):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to