summaryrefslogtreecommitdiffstats
path: root/Modules/posixmodule.c
diff options
context:
space:
mode:
authorEthan Furman <ethan@stoneleaf.us>2016-06-04 19:06:26 (GMT)
committerEthan Furman <ethan@stoneleaf.us>2016-06-04 19:06:26 (GMT)
commit410ef8e23088ab2b8bd92ac70a8176f71da2b931 (patch)
treedceeb23e4a2dcddecc72e0bc6faa15a1177ab633 /Modules/posixmodule.c
parentc55014f3717ce8a810a7e934c8ad5b519dbf88c5 (diff)
downloadcpython-410ef8e23088ab2b8bd92ac70a8176f71da2b931.zip
cpython-410ef8e23088ab2b8bd92ac70a8176f71da2b931.tar.gz
cpython-410ef8e23088ab2b8bd92ac70a8176f71da2b931.tar.bz2
issue27186: add C version of os.fspath(); patch by Jelle Zijlstra
Diffstat (limited to 'Modules/posixmodule.c')
-rw-r--r--Modules/posixmodule.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index ded6d71..c552265 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -12284,6 +12284,56 @@ error:
return NULL;
}
+/*
+ Return the file system path representation of the object.
+
+ If the object is str or bytes, then allow it to pass through with
+ an incremented refcount. If the object defines __fspath__(), then
+ return the result of that method. All other types raise a TypeError.
+*/
+PyObject *
+PyOS_FSPath(PyObject *path)
+{
+ _Py_IDENTIFIER(__fspath__);
+ PyObject *func = NULL;
+ PyObject *path_repr = NULL;
+
+ if (PyUnicode_Check(path) || PyBytes_Check(path)) {
+ Py_INCREF(path);
+ return path;
+ }
+
+ func = _PyObject_LookupSpecial(path, &PyId___fspath__);
+ if (NULL == func) {
+ return PyErr_Format(PyExc_TypeError,
+ "expected str, bytes or os.PathLike object, "
+ "not %S",
+ path->ob_type);
+ }
+
+ path_repr = PyObject_CallFunctionObjArgs(func, NULL);
+ Py_DECREF(func);
+ return path_repr;
+}
+
+/*[clinic input]
+os.fspath
+
+ path: object
+
+Return the file system path representation of the object.
+
+If the object is str or bytes, then allow it to pass through with
+an incremented refcount. If the object defines __fspath__(), then
+return the result of that method. All other types raise a TypeError.
+[clinic start generated code]*/
+
+static PyObject *
+os_fspath_impl(PyModuleDef *module, PyObject *path)
+/*[clinic end generated code: output=51ef0c2772c1932a input=652c7c37e4be1c13]*/
+{
+ return PyOS_FSPath(path);
+}
#include "clinic/posixmodule.c.h"
@@ -12484,6 +12534,7 @@ static PyMethodDef posix_methods[] = {
{"scandir", (PyCFunction)posix_scandir,
METH_VARARGS | METH_KEYWORDS,
posix_scandir__doc__},
+ OS_FSPATH_METHODDEF
{NULL, NULL} /* Sentinel */
};