Author: Matti Picus <[email protected]>
Branch: py3.6
Changeset: r98275:adc2921362d4
Date: 2019-12-12 14:54 +0200
http://bitbucket.org/pypy/pypy/changeset/adc2921362d4/

Log:    test, implement PyOS_FSPath

diff --git a/pypy/module/cpyext/pyfile.py b/pypy/module/cpyext/pyfile.py
--- a/pypy/module/cpyext/pyfile.py
+++ b/pypy/module/cpyext/pyfile.py
@@ -62,3 +62,26 @@
         w_str = space.repr(w_obj)
     space.call_method(w_p, "write", w_str)
     return 0
+
+@cpython_api([PyObject], PyObject)
+def PyOS_FSPath(space, w_path):
+    """
+    Return the file system representation for path. If the object is a str or
+    bytes object, then its reference count is incremented. If the object
+    implements the os.PathLike interface, then __fspath__() is returned as long
+    as it is a str or bytes object. Otherwise TypeError is raised and NULL is
+    returned.
+    """
+    if (space.isinstance_w(w_path, space.w_unicode) or
+        space.isinstance_w(w_path, space.w_bytes)):
+        return w_path
+    if not space.lookup(w_path, '__fspath__'):
+        raise oefmt(space.w_TypeError,
+                "expected str, bytes or os.PathLike object, not %T", w_path)
+    w_ret = space.call_method(w_path, '__fspath__')
+    if (space.isinstance_w(w_ret, space.w_unicode) or
+        space.isinstance_w(w_ret, space.w_bytes)):
+        return w_ret
+    raise oefmt(space.w_TypeError,
+                "expected %T.__fspath__() to return str or bytes, not %T", 
w_path, w_ret)
+
diff --git a/pypy/module/cpyext/test/test_pyfile.py 
b/pypy/module/cpyext/test/test_pyfile.py
--- a/pypy/module/cpyext/test/test_pyfile.py
+++ b/pypy/module/cpyext/test/test_pyfile.py
@@ -1,6 +1,7 @@
 import pytest
 from pypy.module.cpyext.test.test_api import BaseApiTest
 from pypy.module.cpyext.object import Py_PRINT_RAW
+from pypy.interpreter.error import OperationError
 from rpython.rtyper.lltypesystem import rffi
 from rpython.tool.udir import udir
 
@@ -70,3 +71,31 @@
         out, err = capfd.readouterr()
         out = out.replace('\r\n', '\n')
         assert out == "test\n'test\\n'"
+
+    def test_fspath(self, space, api):
+        w_obj = space.newtext("test")
+        w_ret = api.PyOS_FSPath(w_obj)
+        assert space.eq_w(w_ret, w_obj)
+
+        w_obj = space.newint(3)
+        with pytest.raises(OperationError):
+            w_ret = api.PyOS_FSPath(w_obj)
+
+
+        w_p1 = space.appexec([], '''():
+            class Pathlike():
+                def __fspath__(self):
+                    return 'test'
+            return Pathlike()''')
+
+        w_p2 = space.appexec([], '''():
+            class UnPathlike():
+                def __fspath__(self):
+                    return 42
+            return UnPathlike()''')
+
+        w_ret = api.PyOS_FSPath(w_p1)
+        assert space.eq_w(w_ret, space.newtext('test'))
+
+        with pytest.raises(OperationError):
+            w_ret = api.PyOS_FSPath(w_p2)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to