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