https://github.com/python/cpython/commit/964535a13a45cc962a2e35bfaba0fb3867917fd6
commit: 964535a13a45cc962a2e35bfaba0fb3867917fd6
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-09-27T18:56:45+03:00
summary:

gh-155496: Use Argument Clinic for the getpath module (GH-158132)

This also fixes a use after free in isxfile() on Windows: the path was
freed before being passed to CompareStringOrdinal().

files:
A Modules/clinic/getpath.c.h
M Modules/getpath.c

diff --git a/Modules/clinic/getpath.c.h b/Modules/clinic/getpath.c.h
new file mode 100644
index 000000000000000..54ab0240e4482c5
--- /dev/null
+++ b/Modules/clinic/getpath.c.h
@@ -0,0 +1,380 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+#include "pycore_modsupport.h"    // _PyArg_BadArgument()
+
+PyDoc_STRVAR(getpath_abspath__doc__,
+"abspath($module, path, /)\n"
+"--\n"
+"\n"
+"Return the absolute path.");
+
+#define GETPATH_ABSPATH_METHODDEF    \
+    {"abspath", (PyCFunction)getpath_abspath, METH_O, getpath_abspath__doc__},
+
+static PyObject *
+getpath_abspath_impl(PyObject *module, const wchar_t *path);
+
+static PyObject *
+getpath_abspath(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    const wchar_t *path = NULL;
+
+    if (!PyUnicode_Check(arg)) {
+        _PyArg_BadArgument("abspath", "argument", "str", arg);
+        goto exit;
+    }
+    path = PyUnicode_AsWideCharString(arg, NULL);
+    if (path == NULL) {
+        goto exit;
+    }
+    return_value = getpath_abspath_impl(module, path);
+
+exit:
+    /* Cleanup for path */
+    PyMem_Free((void *)path);
+
+    return return_value;
+}
+
+PyDoc_STRVAR(getpath_basename__doc__,
+"basename($module, path, /)\n"
+"--\n"
+"\n"
+"Return the final component of the path.");
+
+#define GETPATH_BASENAME_METHODDEF    \
+    {"basename", (PyCFunction)getpath_basename, METH_O, 
getpath_basename__doc__},
+
+static PyObject *
+getpath_basename_impl(PyObject *module, PyObject *path);
+
+static PyObject *
+getpath_basename(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    PyObject *path;
+
+    if (!PyUnicode_Check(arg)) {
+        _PyArg_BadArgument("basename", "argument", "str", arg);
+        goto exit;
+    }
+    path = arg;
+    return_value = getpath_basename_impl(module, path);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(getpath_dirname__doc__,
+"dirname($module, path, /)\n"
+"--\n"
+"\n"
+"Return the directory component of the path.");
+
+#define GETPATH_DIRNAME_METHODDEF    \
+    {"dirname", (PyCFunction)getpath_dirname, METH_O, getpath_dirname__doc__},
+
+static PyObject *
+getpath_dirname_impl(PyObject *module, PyObject *path);
+
+static PyObject *
+getpath_dirname(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    PyObject *path;
+
+    if (!PyUnicode_Check(arg)) {
+        _PyArg_BadArgument("dirname", "argument", "str", arg);
+        goto exit;
+    }
+    path = arg;
+    return_value = getpath_dirname_impl(module, path);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(getpath_isabs__doc__,
+"isabs($module, path, /)\n"
+"--\n"
+"\n"
+"Return True if the path is absolute.");
+
+#define GETPATH_ISABS_METHODDEF    \
+    {"isabs", (PyCFunction)getpath_isabs, METH_O, getpath_isabs__doc__},
+
+static int
+getpath_isabs_impl(PyObject *module, const wchar_t *path);
+
+static PyObject *
+getpath_isabs(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    const wchar_t *path = NULL;
+    int _return_value;
+
+    if (!PyUnicode_Check(arg)) {
+        _PyArg_BadArgument("isabs", "argument", "str", arg);
+        goto exit;
+    }
+    path = PyUnicode_AsWideCharString(arg, NULL);
+    if (path == NULL) {
+        goto exit;
+    }
+    _return_value = getpath_isabs_impl(module, path);
+    if ((_return_value == -1) && PyErr_Occurred()) {
+        goto exit;
+    }
+    return_value = PyBool_FromLong((long)_return_value);
+
+exit:
+    /* Cleanup for path */
+    PyMem_Free((void *)path);
+
+    return return_value;
+}
+
+PyDoc_STRVAR(getpath_hassuffix__doc__,
+"hassuffix($module, path, suffix, /)\n"
+"--\n"
+"\n"
+"Return True if the path ends with the suffix, ignoring the case.");
+
+#define GETPATH_HASSUFFIX_METHODDEF    \
+    {"hassuffix", _PyCFunction_CAST(getpath_hassuffix), METH_FASTCALL, 
getpath_hassuffix__doc__},
+
+static int
+getpath_hassuffix_impl(PyObject *module, PyObject *pathobj,
+                       PyObject *suffixobj);
+
+static PyObject *
+getpath_hassuffix(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *pathobj;
+    PyObject *suffixobj;
+    int _return_value;
+
+    if (!_PyArg_CheckPositional("hassuffix", nargs, 2, 2)) {
+        goto exit;
+    }
+    if (!PyUnicode_Check(args[0])) {
+        _PyArg_BadArgument("hassuffix", "argument 1", "str", args[0]);
+        goto exit;
+    }
+    pathobj = args[0];
+    if (!PyUnicode_Check(args[1])) {
+        _PyArg_BadArgument("hassuffix", "argument 2", "str", args[1]);
+        goto exit;
+    }
+    suffixobj = args[1];
+    _return_value = getpath_hassuffix_impl(module, pathobj, suffixobj);
+    if ((_return_value == -1) && PyErr_Occurred()) {
+        goto exit;
+    }
+    return_value = PyBool_FromLong((long)_return_value);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(getpath_isdir__doc__,
+"isdir($module, path, /)\n"
+"--\n"
+"\n"
+"Return True if the path is a directory.");
+
+#define GETPATH_ISDIR_METHODDEF    \
+    {"isdir", (PyCFunction)getpath_isdir, METH_O, getpath_isdir__doc__},
+
+static int
+getpath_isdir_impl(PyObject *module, const wchar_t *path);
+
+static PyObject *
+getpath_isdir(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    const wchar_t *path = NULL;
+    int _return_value;
+
+    if (!PyUnicode_Check(arg)) {
+        _PyArg_BadArgument("isdir", "argument", "str", arg);
+        goto exit;
+    }
+    path = PyUnicode_AsWideCharString(arg, NULL);
+    if (path == NULL) {
+        goto exit;
+    }
+    _return_value = getpath_isdir_impl(module, path);
+    if ((_return_value == -1) && PyErr_Occurred()) {
+        goto exit;
+    }
+    return_value = PyBool_FromLong((long)_return_value);
+
+exit:
+    /* Cleanup for path */
+    PyMem_Free((void *)path);
+
+    return return_value;
+}
+
+PyDoc_STRVAR(getpath_isfile__doc__,
+"isfile($module, path, /)\n"
+"--\n"
+"\n"
+"Return True if the path is a regular file.");
+
+#define GETPATH_ISFILE_METHODDEF    \
+    {"isfile", (PyCFunction)getpath_isfile, METH_O, getpath_isfile__doc__},
+
+static int
+getpath_isfile_impl(PyObject *module, PyObject *pathobj);
+
+static PyObject *
+getpath_isfile(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    PyObject *pathobj;
+    int _return_value;
+
+    if (!PyUnicode_Check(arg)) {
+        _PyArg_BadArgument("isfile", "argument", "str", arg);
+        goto exit;
+    }
+    pathobj = arg;
+    _return_value = getpath_isfile_impl(module, pathobj);
+    if ((_return_value == -1) && PyErr_Occurred()) {
+        goto exit;
+    }
+    return_value = PyBool_FromLong((long)_return_value);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(getpath_isxfile__doc__,
+"isxfile($module, path, /)\n"
+"--\n"
+"\n"
+"Return True if the path is an executable file.");
+
+#define GETPATH_ISXFILE_METHODDEF    \
+    {"isxfile", (PyCFunction)getpath_isxfile, METH_O, getpath_isxfile__doc__},
+
+static int
+getpath_isxfile_impl(PyObject *module, PyObject *pathobj);
+
+static PyObject *
+getpath_isxfile(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    PyObject *pathobj;
+    int _return_value;
+
+    if (!PyUnicode_Check(arg)) {
+        _PyArg_BadArgument("isxfile", "argument", "str", arg);
+        goto exit;
+    }
+    pathobj = arg;
+    _return_value = getpath_isxfile_impl(module, pathobj);
+    if ((_return_value == -1) && PyErr_Occurred()) {
+        goto exit;
+    }
+    return_value = PyBool_FromLong((long)_return_value);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(getpath_joinpath__doc__,
+"joinpath($module, /, *args)\n"
+"--\n"
+"\n"
+"Join the path components.");
+
+#define GETPATH_JOINPATH_METHODDEF    \
+    {"joinpath", _PyCFunction_CAST(getpath_joinpath), METH_FASTCALL, 
getpath_joinpath__doc__},
+
+static PyObject *
+getpath_joinpath_impl(PyObject *module, PyObject *args);
+
+static PyObject *
+getpath_joinpath(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *__clinic_args = NULL;
+
+    __clinic_args = PyTuple_FromArray(args, nargs);
+    if (__clinic_args == NULL) {
+        goto exit;
+    }
+    return_value = getpath_joinpath_impl(module, __clinic_args);
+
+exit:
+    /* Cleanup for args */
+    Py_XDECREF(__clinic_args);
+
+    return return_value;
+}
+
+PyDoc_STRVAR(getpath_readlines__doc__,
+"readlines($module, path, /)\n"
+"--\n"
+"\n"
+"Return the lines of the file.");
+
+#define GETPATH_READLINES_METHODDEF    \
+    {"readlines", (PyCFunction)getpath_readlines, METH_O, 
getpath_readlines__doc__},
+
+static PyObject *
+getpath_readlines_impl(PyObject *module, PyObject *pathobj);
+
+static PyObject *
+getpath_readlines(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    PyObject *pathobj;
+
+    if (!PyUnicode_Check(arg)) {
+        _PyArg_BadArgument("readlines", "argument", "str", arg);
+        goto exit;
+    }
+    pathobj = arg;
+    return_value = getpath_readlines_impl(module, pathobj);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(getpath_realpath__doc__,
+"realpath($module, path, /)\n"
+"--\n"
+"\n"
+"Resolve a symlinked file.");
+
+#define GETPATH_REALPATH_METHODDEF    \
+    {"realpath", (PyCFunction)getpath_realpath, METH_O, 
getpath_realpath__doc__},
+
+static PyObject *
+getpath_realpath_impl(PyObject *module, PyObject *pathobj);
+
+static PyObject *
+getpath_realpath(PyObject *module, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    PyObject *pathobj;
+
+    if (!PyUnicode_Check(arg)) {
+        _PyArg_BadArgument("realpath", "argument", "str", arg);
+        goto exit;
+    }
+    pathobj = arg;
+    return_value = getpath_realpath_impl(module, pathobj);
+
+exit:
+    return return_value;
+}
+/*[clinic end generated code: output=74266cdd2d87e28d input=a9049054013a1b77]*/
diff --git a/Modules/getpath.c b/Modules/getpath.c
index ed41536acbcc813..48047de0c12af2d 100644
--- a/Modules/getpath.c
+++ b/Modules/getpath.c
@@ -58,40 +58,52 @@
 #endif
 
 
+/*[clinic input]
+module getpath
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b425aa3ea7292100]*/
+
+#include "clinic/getpath.c.h"
+
 /* HELPER FUNCTIONS for getpath.py */
 
+/*[clinic input]
+getpath.abspath
+
+    path: Py_UNICODE
+    /
+
+Return the absolute path.
+[clinic start generated code]*/
+
 static PyObject *
-getpath_abspath(PyObject *Py_UNUSED(self), PyObject *args)
+getpath_abspath_impl(PyObject *module, const wchar_t *path)
+/*[clinic end generated code: output=5009336e32e75b9b input=0fd554ce535744f2]*/
 {
-    PyObject *r = NULL;
-    PyObject *pathobj;
-    wchar_t *path;
-    if (!PyArg_ParseTuple(args, "U", &pathobj)) {
+    wchar_t *abs;
+    if (_Py_abspath(_Py_normpath((wchar_t *)path, -1), &abs) < 0 || abs == 
NULL) {
+        PyErr_SetString(PyExc_OSError, "failed to make path absolute");
         return NULL;
     }
-    Py_ssize_t len;
-    path = PyUnicode_AsWideCharString(pathobj, &len);
-    if (path) {
-        wchar_t *abs;
-        if (_Py_abspath((const wchar_t *)_Py_normpath(path, -1), &abs) == 0 && 
abs) {
-            r = PyUnicode_FromWideChar(abs, -1);
-            PyMem_RawFree((void *)abs);
-        } else {
-            PyErr_SetString(PyExc_OSError, "failed to make path absolute");
-        }
-        PyMem_Free((void *)path);
-    }
+    PyObject *r = PyUnicode_FromWideChar(abs, -1);
+    PyMem_RawFree((void *)abs);
     return r;
 }
 
 
+/*[clinic input]
+getpath.basename
+
+    path: unicode
+    /
+
+Return the final component of the path.
+[clinic start generated code]*/
+
 static PyObject *
-getpath_basename(PyObject *Py_UNUSED(self), PyObject *args)
+getpath_basename_impl(PyObject *module, PyObject *path)
+/*[clinic end generated code: output=d383d3b34842236e input=0de5b71fc78bbad8]*/
 {
-    PyObject *path;
-    if (!PyArg_ParseTuple(args, "U", &path)) {
-        return NULL;
-    }
     Py_ssize_t end = PyUnicode_GET_LENGTH(path);
     Py_ssize_t pos = PyUnicode_FindChar(path, SEP, 0, end, -1);
     if (pos < 0) {
@@ -101,13 +113,19 @@ getpath_basename(PyObject *Py_UNUSED(self), PyObject 
*args)
 }
 
 
+/*[clinic input]
+getpath.dirname
+
+    path: unicode
+    /
+
+Return the directory component of the path.
+[clinic start generated code]*/
+
 static PyObject *
-getpath_dirname(PyObject *Py_UNUSED(self), PyObject *args)
+getpath_dirname_impl(PyObject *module, PyObject *path)
+/*[clinic end generated code: output=6887a025f5f6784c input=0c33269fe28957fb]*/
 {
-    PyObject *path;
-    if (!PyArg_ParseTuple(args, "U", &path)) {
-        return NULL;
-    }
     Py_ssize_t end = PyUnicode_GET_LENGTH(path);
     Py_ssize_t pos = PyUnicode_FindChar(path, SEP, 0, end, -1);
     if (pos < 0) {
@@ -117,51 +135,51 @@ getpath_dirname(PyObject *Py_UNUSED(self), PyObject *args)
 }
 
 
-static PyObject *
-getpath_isabs(PyObject *Py_UNUSED(self), PyObject *args)
+/*[clinic input]
+getpath.isabs -> bool
+
+    path: Py_UNICODE
+    /
+
+Return True if the path is absolute.
+[clinic start generated code]*/
+
+static int
+getpath_isabs_impl(PyObject *module, const wchar_t *path)
+/*[clinic end generated code: output=4659b9e6f088c2ca input=04931a206cdd77f6]*/
 {
-    PyObject *r = NULL;
-    PyObject *pathobj;
-    const wchar_t *path;
-    if (!PyArg_ParseTuple(args, "U", &pathobj)) {
-        return NULL;
-    }
-    path = PyUnicode_AsWideCharString(pathobj, NULL);
-    if (path) {
-        r = _Py_isabs(path) ? Py_True : Py_False;
-        PyMem_Free((void *)path);
-    }
-    return Py_XNewRef(r);
+    return _Py_isabs(path);
 }
 
 
-static PyObject *
-getpath_hassuffix(PyObject *Py_UNUSED(self), PyObject *args)
+/*[clinic input]
+getpath.hassuffix -> bool
+
+    path as pathobj: unicode
+    suffix as suffixobj: unicode
+    /
+
+Return True if the path ends with the suffix, ignoring the case.
+[clinic start generated code]*/
+
+static int
+getpath_hassuffix_impl(PyObject *module, PyObject *pathobj,
+                       PyObject *suffixobj)
+/*[clinic end generated code: output=c4cbd6f2f567f83c input=4b477740575b94d8]*/
 {
-    PyObject *r = NULL;
-    PyObject *pathobj;
-    PyObject *suffixobj;
-    const wchar_t *path;
-    const wchar_t *suffix;
-    if (!PyArg_ParseTuple(args, "UU", &pathobj, &suffixobj)) {
-        return NULL;
-    }
+    int r = -1;
     Py_ssize_t len, suffixLen;
-    path = PyUnicode_AsWideCharString(pathobj, &len);
+    const wchar_t *path = PyUnicode_AsWideCharString(pathobj, &len);
     if (path) {
-        suffix = PyUnicode_AsWideCharString(suffixobj, &suffixLen);
+        const wchar_t *suffix = PyUnicode_AsWideCharString(suffixobj,
+                                                          &suffixLen);
         if (suffix) {
-            if (suffixLen > len ||
+            r = suffixLen <= len &&
 #ifdef MS_WINDOWS
-                wcsicmp(&path[len - suffixLen], suffix) != 0
+                wcsicmp(&path[len - suffixLen], suffix) == 0;
 #else
-                wcscmp(&path[len - suffixLen], suffix) != 0
+                wcscmp(&path[len - suffixLen], suffix) == 0;
 #endif
-            ) {
-                r = Py_NewRef(Py_False);
-            } else {
-                r = Py_NewRef(Py_True);
-            }
             PyMem_Free((void *)suffix);
         }
         PyMem_Free((void *)path);
@@ -170,105 +188,114 @@ getpath_hassuffix(PyObject *Py_UNUSED(self), PyObject 
*args)
 }
 
 
-static PyObject *
-getpath_isdir(PyObject *Py_UNUSED(self), PyObject *args)
+/*[clinic input]
+getpath.isdir -> bool
+
+    path: Py_UNICODE
+    /
+
+Return True if the path is a directory.
+[clinic start generated code]*/
+
+static int
+getpath_isdir_impl(PyObject *module, const wchar_t *path)
+/*[clinic end generated code: output=467820dd83daa7a6 input=0ddd588cd5357a9a]*/
 {
-    PyObject *r = NULL;
-    PyObject *pathobj;
-    const wchar_t *path;
-    if (!PyArg_ParseTuple(args, "U", &pathobj)) {
-        return NULL;
-    }
-    path = PyUnicode_AsWideCharString(pathobj, NULL);
-    if (path) {
 #ifdef MS_WINDOWS
-        DWORD attr = GetFileAttributesW(path);
-        r = (attr != INVALID_FILE_ATTRIBUTES) &&
-            (attr & FILE_ATTRIBUTE_DIRECTORY) ? Py_True : Py_False;
+    DWORD attr = GetFileAttributesW(path);
+    return (attr != INVALID_FILE_ATTRIBUTES)
+           && (attr & FILE_ATTRIBUTE_DIRECTORY);
 #else
-        struct stat st;
-        r = (_Py_wstat(path, &st) == 0) && S_ISDIR(st.st_mode) ? Py_True : 
Py_False;
+    struct stat st;
+    return (_Py_wstat(path, &st) == 0) && S_ISDIR(st.st_mode);
 #endif
-        PyMem_Free((void *)path);
-    }
-    return Py_XNewRef(r);
 }
 
 
-static PyObject *
-getpath_isfile(PyObject *Py_UNUSED(self), PyObject *args)
-{
-    PyObject *pathobj;
-    if (!PyArg_ParseTuple(args, "U", &pathobj)) {
-        return NULL;
-    }
+/*[clinic input]
+getpath.isfile -> bool
+
+    path as pathobj: unicode
+    /
 
-    int isfile;
+Return True if the path is a regular file.
+[clinic start generated code]*/
+
+static int
+getpath_isfile_impl(PyObject *module, PyObject *pathobj)
+/*[clinic end generated code: output=197acb7a5434b9d1 input=ba1c2746ec8f2f47]*/
+{
 #ifdef MS_WINDOWS
     wchar_t *path = PyUnicode_AsWideCharString(pathobj, NULL);
     if (path == NULL) {
-        return NULL;
+        return -1;
     }
 
     DWORD attr = GetFileAttributesW(path);
     PyMem_Free(path);
-    isfile = ((attr != INVALID_FILE_ATTRIBUTES)
-               && !(attr & FILE_ATTRIBUTE_DIRECTORY));
+    return (attr != INVALID_FILE_ATTRIBUTES)
+           && !(attr & FILE_ATTRIBUTE_DIRECTORY);
 #else
     struct stat st;
     int res = _Py_stat(pathobj, &st);
     if (res == -2) {
-        return NULL;
+        return -1;
     }
-    isfile = ((res == 0) && S_ISREG(st.st_mode));
+    return (res == 0) && S_ISREG(st.st_mode);
 #endif
-    return PyBool_FromLong(isfile);
 }
 
 
-static PyObject *
-getpath_isxfile(PyObject *Py_UNUSED(self), PyObject *args)
-{
-    PyObject *pathobj;
-    if (!PyArg_ParseTuple(args, "U", &pathobj)) {
-        return NULL;
-    }
+/*[clinic input]
+getpath.isxfile -> bool
+
+    path as pathobj: unicode
+    /
+
+Return True if the path is an executable file.
+[clinic start generated code]*/
 
-    int isxfile;
+static int
+getpath_isxfile_impl(PyObject *module, PyObject *pathobj)
+/*[clinic end generated code: output=2f0bc6708d945bc8 input=6d99faa90e262511]*/
+{
 #ifdef MS_WINDOWS
     Py_ssize_t cchPath;
     wchar_t *path = PyUnicode_AsWideCharString(pathobj, &cchPath);
     if (path == NULL) {
-        return NULL;
+        return -1;
     }
 
     DWORD attr = GetFileAttributesW(path);
+    int isxfile = (attr != INVALID_FILE_ATTRIBUTES) &&
+                  !(attr & FILE_ATTRIBUTE_DIRECTORY) &&
+                  (cchPath >= 4) &&
+                  (CompareStringOrdinal(path + cchPath - 4, -1, L".exe", -1, 1 
/* ignore case */) == CSTR_EQUAL);
     PyMem_Free(path);
-    isxfile = (attr != INVALID_FILE_ATTRIBUTES) &&
-              !(attr & FILE_ATTRIBUTE_DIRECTORY) &&
-              (cchPath >= 4) &&
-              (CompareStringOrdinal(path + cchPath - 4, -1, L".exe", -1, 1 /* 
ignore case */) == CSTR_EQUAL);
+    return isxfile;
 #else
     struct stat st;
     int res = _Py_stat(pathobj, &st);
     if (res == -2) {
-        return NULL;
+        return -1;
     }
-    isxfile = ((res == 0)
-               && S_ISREG(st.st_mode)
-               && (st.st_mode & 0111));
+    return (res == 0) && S_ISREG(st.st_mode) && (st.st_mode & 0111);
 #endif
-    return PyBool_FromLong(isxfile);
 }
 
 
+/*[clinic input]
+getpath.joinpath
+
+    *args: tuple
+
+Join the path components.
+[clinic start generated code]*/
+
 static PyObject *
-getpath_joinpath(PyObject *Py_UNUSED(self), PyObject *args)
+getpath_joinpath_impl(PyObject *module, PyObject *args)
+/*[clinic end generated code: output=0044d429b32e5f5a input=5c67eeca4a6d1413]*/
 {
-    if (!PyTuple_Check(args)) {
-        PyErr_SetString(PyExc_TypeError, "requires tuple of arguments");
-        return NULL;
-    }
     Py_ssize_t n = PyTuple_GET_SIZE(args);
     if (n == 0) {
         return Py_GetConstant(Py_CONSTANT_EMPTY_STR);
@@ -347,13 +374,19 @@ getpath_joinpath(PyObject *Py_UNUSED(self), PyObject 
*args)
 }
 
 
+/*[clinic input]
+getpath.readlines
+
+    path as pathobj: unicode
+    /
+
+Return the lines of the file.
+[clinic start generated code]*/
+
 static PyObject *
-getpath_readlines(PyObject *Py_UNUSED(self), PyObject *args)
+getpath_readlines_impl(PyObject *module, PyObject *pathobj)
+/*[clinic end generated code: output=6a7c1a1d2bb23046 input=6f54150f72789b78]*/
 {
-    PyObject *pathobj;
-    if (!PyArg_ParseTuple(args, "U", &pathobj)) {
-        return NULL;
-    }
     FILE *fp = Py_fopen(pathobj, "rb");
     if (!fp) {
         return NULL;
@@ -423,13 +456,19 @@ getpath_readlines(PyObject *Py_UNUSED(self), PyObject 
*args)
 }
 
 
+/*[clinic input]
+getpath.realpath
+
+    path as pathobj: unicode
+    /
+
+Resolve a symlinked file.
+[clinic start generated code]*/
+
 static PyObject *
-getpath_realpath(PyObject *Py_UNUSED(self) , PyObject *args)
+getpath_realpath_impl(PyObject *module, PyObject *pathobj)
+/*[clinic end generated code: output=8559260e3786874e input=d3c5eee0ddd2c3e2]*/
 {
-    PyObject *pathobj;
-    if (!PyArg_ParseTuple(args, "U", &pathobj)) {
-        return NULL;
-    }
 #if defined(HAVE_READLINK)
     /* This readlink calculation only resolves a symlinked file, and
        does not resolve any path segments. This is consistent with
@@ -566,17 +605,17 @@ getpath_realpath(PyObject *Py_UNUSED(self) , PyObject 
*args)
 
 
 static PyMethodDef getpath_methods[] = {
-    {"abspath", getpath_abspath, METH_VARARGS, NULL},
-    {"basename", getpath_basename, METH_VARARGS, NULL},
-    {"dirname", getpath_dirname, METH_VARARGS, NULL},
-    {"hassuffix", getpath_hassuffix, METH_VARARGS, NULL},
-    {"isabs", getpath_isabs, METH_VARARGS, NULL},
-    {"isdir", getpath_isdir, METH_VARARGS, NULL},
-    {"isfile", getpath_isfile, METH_VARARGS, NULL},
-    {"isxfile", getpath_isxfile, METH_VARARGS, NULL},
-    {"joinpath", getpath_joinpath, METH_VARARGS, NULL},
-    {"readlines", getpath_readlines, METH_VARARGS, NULL},
-    {"realpath", getpath_realpath, METH_VARARGS, NULL},
+    GETPATH_ABSPATH_METHODDEF
+    GETPATH_BASENAME_METHODDEF
+    GETPATH_DIRNAME_METHODDEF
+    GETPATH_HASSUFFIX_METHODDEF
+    GETPATH_ISABS_METHODDEF
+    GETPATH_ISDIR_METHODDEF
+    GETPATH_ISFILE_METHODDEF
+    GETPATH_ISXFILE_METHODDEF
+    GETPATH_JOINPATH_METHODDEF
+    GETPATH_READLINES_METHODDEF
+    GETPATH_REALPATH_METHODDEF
     {NULL, NULL, 0, NULL}
 };
 

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to