From f30fd64291d11117511197c8b96ad68718318e15 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 22 Aug 2026 11:30:12 +0300 Subject: [PATCH] gh-155496: Use Argument Clinic for the getpath module --- Modules/clinic/getpath.c.h | 337 +++++++++++++++++++++++++++++++++++++ Modules/getpath.c | 207 +++++++++++++++-------- 2 files changed, 477 insertions(+), 67 deletions(-) create mode 100644 Modules/clinic/getpath.c.h diff --git a/Modules/clinic/getpath.c.h b/Modules/clinic/getpath.c.h new file mode 100644 index 00000000000000..c1e44aed73b5f6 --- /dev/null +++ b/Modules/clinic/getpath.c.h @@ -0,0 +1,337 @@ +/*[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, PyObject *pathobj); + +static PyObject * +getpath_abspath(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *pathobj; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("abspath", "argument", "str", arg); + goto exit; + } + pathobj = arg; + return_value = getpath_abspath_impl(module, pathobj); + +exit: + 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 PyObject * +getpath_isabs_impl(PyObject *module, PyObject *pathobj); + +static PyObject * +getpath_isabs(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *pathobj; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("isabs", "argument", "str", arg); + goto exit; + } + pathobj = arg; + return_value = getpath_isabs_impl(module, pathobj); + +exit: + 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 PyObject * +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; + + 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); + +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 PyObject * +getpath_isdir_impl(PyObject *module, PyObject *pathobj); + +static PyObject * +getpath_isdir(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *pathobj; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("isdir", "argument", "str", arg); + goto exit; + } + pathobj = arg; + return_value = getpath_isdir_impl(module, pathobj); + +exit: + 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 PyObject * +getpath_isfile_impl(PyObject *module, PyObject *pathobj); + +static PyObject * +getpath_isfile(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *pathobj; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("isfile", "argument", "str", arg); + goto exit; + } + pathobj = arg; + return_value = getpath_isfile_impl(module, pathobj); + +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 PyObject * +getpath_isxfile_impl(PyObject *module, PyObject *pathobj); + +static PyObject * +getpath_isxfile(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *pathobj; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("isxfile", "argument", "str", arg); + goto exit; + } + pathobj = arg; + return_value = getpath_isxfile_impl(module, pathobj); + +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=766f73e4b40e9192 input=a9049054013a1b77]*/ diff --git a/Modules/getpath.c b/Modules/getpath.c index ed41536acbcc81..6a24018d36414e 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -58,17 +58,30 @@ #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 as pathobj: unicode + / + +Return the absolute path. +[clinic start generated code]*/ + static PyObject * -getpath_abspath(PyObject *Py_UNUSED(self), PyObject *args) +getpath_abspath_impl(PyObject *module, PyObject *pathobj) +/*[clinic end generated code: output=a307fc0d5d82eb2e input=2f8179427a1a31a6]*/ { PyObject *r = NULL; - PyObject *pathobj; wchar_t *path; - if (!PyArg_ParseTuple(args, "U", &pathobj)) { - return NULL; - } Py_ssize_t len; path = PyUnicode_AsWideCharString(pathobj, &len); if (path) { @@ -85,13 +98,19 @@ getpath_abspath(PyObject *Py_UNUSED(self), PyObject *args) } +/*[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 +120,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,15 +142,21 @@ getpath_dirname(PyObject *Py_UNUSED(self), PyObject *args) } +/*[clinic input] +getpath.isabs + + path as pathobj: unicode + / + +Return True if the path is absolute. +[clinic start generated code]*/ + static PyObject * -getpath_isabs(PyObject *Py_UNUSED(self), PyObject *args) +getpath_isabs_impl(PyObject *module, PyObject *pathobj) +/*[clinic end generated code: output=7f5c62037d0b2c86 input=e49d90a186348140]*/ { 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; @@ -135,17 +166,24 @@ getpath_isabs(PyObject *Py_UNUSED(self), PyObject *args) } +/*[clinic input] +getpath.hassuffix + + 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 PyObject * -getpath_hassuffix(PyObject *Py_UNUSED(self), PyObject *args) +getpath_hassuffix_impl(PyObject *module, PyObject *pathobj, + PyObject *suffixobj) +/*[clinic end generated code: output=40e52a2ebe497e47 input=dffaf0ddc9d63647]*/ { PyObject *r = NULL; - PyObject *pathobj; - PyObject *suffixobj; const wchar_t *path; const wchar_t *suffix; - if (!PyArg_ParseTuple(args, "UU", &pathobj, &suffixobj)) { - return NULL; - } Py_ssize_t len, suffixLen; path = PyUnicode_AsWideCharString(pathobj, &len); if (path) { @@ -170,15 +208,21 @@ getpath_hassuffix(PyObject *Py_UNUSED(self), PyObject *args) } +/*[clinic input] +getpath.isdir + + path as pathobj: unicode + / + +Return True if the path is a directory. +[clinic start generated code]*/ + static PyObject * -getpath_isdir(PyObject *Py_UNUSED(self), PyObject *args) +getpath_isdir_impl(PyObject *module, PyObject *pathobj) +/*[clinic end generated code: output=5af217f29e968e1b input=d1d4c4d74d2e37f1]*/ { 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 @@ -195,13 +239,19 @@ getpath_isdir(PyObject *Py_UNUSED(self), PyObject *args) } +/*[clinic input] +getpath.isfile + + path as pathobj: unicode + / + +Return True if the path is a regular file. +[clinic start generated code]*/ + static PyObject * -getpath_isfile(PyObject *Py_UNUSED(self), PyObject *args) +getpath_isfile_impl(PyObject *module, PyObject *pathobj) +/*[clinic end generated code: output=0060d782bd507740 input=71831c61d25e3f9e]*/ { - PyObject *pathobj; - if (!PyArg_ParseTuple(args, "U", &pathobj)) { - return NULL; - } int isfile; #ifdef MS_WINDOWS @@ -226,13 +276,19 @@ getpath_isfile(PyObject *Py_UNUSED(self), PyObject *args) } +/*[clinic input] +getpath.isxfile + + path as pathobj: unicode + / + +Return True if the path is an executable file. +[clinic start generated code]*/ + static PyObject * -getpath_isxfile(PyObject *Py_UNUSED(self), PyObject *args) +getpath_isxfile_impl(PyObject *module, PyObject *pathobj) +/*[clinic end generated code: output=67348f84968ac985 input=4b272be4846d89a2]*/ { - PyObject *pathobj; - if (!PyArg_ParseTuple(args, "U", &pathobj)) { - return NULL; - } int isxfile; #ifdef MS_WINDOWS @@ -262,13 +318,18 @@ getpath_isxfile(PyObject *Py_UNUSED(self), PyObject *args) } +/*[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 +408,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 +490,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 +639,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} };