From ae2e171f2a9e79db9f31547f2c8163f8b7c497b9 Mon Sep 17 00:00:00 2001 From: nineteendo Date: Sat, 27 Apr 2024 22:28:52 +0200 Subject: [PATCH 01/26] Add `null_embeddable` --- Include/unicodeobject.h | 1 + Modules/clinic/posixmodule.c.h | 168 ++++++++++++++++++--------------- Modules/posixmodule.c | 145 ++++++++++++---------------- Objects/unicodeobject.c | 10 +- 4 files changed, 165 insertions(+), 159 deletions(-) diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index dee00715b3c51d..cdeabee9d7aa68 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -740,6 +740,7 @@ PyAPI_FUNC(PyObject*) PyUnicode_EncodeLocale( /* ParseTuple converter: encode str objects to bytes using PyUnicode_EncodeFSDefault(); bytes objects are output as-is. */ +extern int _PyUnicode_FSConverter(PyObject*, void*, int); PyAPI_FUNC(int) PyUnicode_FSConverter(PyObject*, void*); /* ParseTuple converter: decode bytes objects to unicode using diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index a0d1f3238a6733..b6a582f6e81cfa 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -72,7 +72,7 @@ os_stat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("stat", "path", 0, 1); + path_t path = PATH_T_INITIALIZE("stat", "path", 0, 0, 1); int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; @@ -154,7 +154,7 @@ os_lstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -250,7 +250,7 @@ os_access(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("access", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("access", "path", 0, 0, 0); int mode; int dir_fd = DEFAULT_DIR_FD; int effective_ids = 0; @@ -409,7 +409,7 @@ os_chdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("chdir", "path", 0, PATH_HAVE_FCHDIR); + path_t path = PATH_T_INITIALIZE("chdir", "path", 0, 0, PATH_HAVE_FCHDIR); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -560,7 +560,7 @@ os_chmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("chmod", "path", 0, PATH_HAVE_FCHMOD); + path_t path = PATH_T_INITIALIZE("chmod", "path", 0, 0, PATH_HAVE_FCHMOD); int mode; int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = CHMOD_DEFAULT_FOLLOW_SYMLINKS; @@ -725,7 +725,7 @@ os_lchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0, 0); int mode; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -802,7 +802,7 @@ os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0, 0); unsigned long flags; int follow_symlinks = 1; @@ -884,7 +884,7 @@ os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject }; #undef KWTUPLE PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0, 0); unsigned long flags; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -954,7 +954,7 @@ os_chroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -1190,7 +1190,7 @@ os_chown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE("chown", "path", 0, PATH_HAVE_FCHOWN); + path_t path = PATH_T_INITIALIZE("chown", "path", 0, 0, PATH_HAVE_FCHOWN); uid_t uid; gid_t gid; int dir_fd = DEFAULT_DIR_FD; @@ -1355,7 +1355,7 @@ os_lchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[3]; - path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0, 0); uid_t uid; gid_t gid; @@ -1476,8 +1476,8 @@ os_link(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE("link", "src", 0, 0); - path_t dst = PATH_T_INITIALIZE("link", "dst", 0, 0); + path_t src = PATH_T_INITIALIZE("link", "src", 0, 0, 0); + path_t dst = PATH_T_INITIALIZE("link", "dst", 0, 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; @@ -1583,7 +1583,7 @@ os_listdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - path_t path = PATH_T_INITIALIZE("listdir", "path", 1, PATH_HAVE_FDOPENDIR); + path_t path = PATH_T_INITIALIZE("listdir", "path", 1, 0, PATH_HAVE_FDOPENDIR); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { @@ -1699,7 +1699,7 @@ os_listmounts(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t volume = PATH_T_INITIALIZE("listmounts", "volume", 0, 0); + path_t volume = PATH_T_INITIALIZE("listmounts", "volume", 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -1763,7 +1763,7 @@ os__path_isdevdrive(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_path_isdevdrive", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("_path_isdevdrive", "path", 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -1800,7 +1800,7 @@ static PyObject * os__getfullpathname(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE("_getfullpathname", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("_getfullpathname", "path", 0, 0, 0); if (!path_converter(arg, &path)) { goto exit; @@ -1834,7 +1834,7 @@ static PyObject * os__getfinalpathname(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE("_getfinalpathname", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("_getfinalpathname", "path", 0, 0, 0); if (!path_converter(arg, &path)) { goto exit; @@ -1868,7 +1868,7 @@ static PyObject * os__findfirstfile(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE("_findfirstfile", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("_findfirstfile", "path", 0, 0, 0); if (!path_converter(arg, &path)) { goto exit; @@ -1928,7 +1928,7 @@ os__getvolumepathname(PyObject *module, PyObject *const *args, Py_ssize_t nargs, }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_getvolumepathname", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("_getvolumepathname", "path", 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -1992,7 +1992,7 @@ os__path_splitroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_path_splitroot", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("_path_splitroot", "path", 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -2024,7 +2024,7 @@ PyDoc_STRVAR(os__path_isdir__doc__, {"_path_isdir", _PyCFunction_CAST(os__path_isdir), METH_FASTCALL|METH_KEYWORDS, os__path_isdir__doc__}, static PyObject * -os__path_isdir_impl(PyObject *module, PyObject *s); +os__path_isdir_impl(PyObject *module, path_t *path); static PyObject * os__path_isdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -2056,16 +2056,21 @@ os__path_isdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *s; + path_t path = PATH_T_INITIALIZE("_path_isdir", "path", 0, 1, 1); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - s = args[0]; - return_value = os__path_isdir_impl(module, s); + if (!path_converter(args[0], &path)) { + goto exit; + } + return_value = os__path_isdir_impl(module, &path); exit: + /* Cleanup for path */ + path_cleanup(&path); + return return_value; } @@ -2083,7 +2088,7 @@ PyDoc_STRVAR(os__path_isfile__doc__, {"_path_isfile", _PyCFunction_CAST(os__path_isfile), METH_FASTCALL|METH_KEYWORDS, os__path_isfile__doc__}, static PyObject * -os__path_isfile_impl(PyObject *module, PyObject *path); +os__path_isfile_impl(PyObject *module, path_t *path); static PyObject * os__path_isfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -2115,16 +2120,21 @@ os__path_isfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *path; + path_t path = PATH_T_INITIALIZE("_path_isfile", "path", 0, 1, 1); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - path = args[0]; - return_value = os__path_isfile_impl(module, path); + if (!path_converter(args[0], &path)) { + goto exit; + } + return_value = os__path_isfile_impl(module, &path); exit: + /* Cleanup for path */ + path_cleanup(&path); + return return_value; } @@ -2142,7 +2152,7 @@ PyDoc_STRVAR(os__path_exists__doc__, {"_path_exists", _PyCFunction_CAST(os__path_exists), METH_FASTCALL|METH_KEYWORDS, os__path_exists__doc__}, static PyObject * -os__path_exists_impl(PyObject *module, PyObject *path); +os__path_exists_impl(PyObject *module, path_t *path); static PyObject * os__path_exists(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -2174,16 +2184,21 @@ os__path_exists(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *path; + path_t path = PATH_T_INITIALIZE("_path_exists", "path", 0, 1, 1); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - path = args[0]; - return_value = os__path_exists_impl(module, path); + if (!path_converter(args[0], &path)) { + goto exit; + } + return_value = os__path_exists_impl(module, &path); exit: + /* Cleanup for path */ + path_cleanup(&path); + return return_value; } @@ -2201,7 +2216,7 @@ PyDoc_STRVAR(os__path_islink__doc__, {"_path_islink", _PyCFunction_CAST(os__path_islink), METH_FASTCALL|METH_KEYWORDS, os__path_islink__doc__}, static PyObject * -os__path_islink_impl(PyObject *module, PyObject *path); +os__path_islink_impl(PyObject *module, path_t *path); static PyObject * os__path_islink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -2233,16 +2248,21 @@ os__path_islink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *path; + path_t path = PATH_T_INITIALIZE("_path_islink", "path", 0, 1, 1); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - path = args[0]; - return_value = os__path_islink_impl(module, path); + if (!path_converter(args[0], &path)) { + goto exit; + } + return_value = os__path_islink_impl(module, &path); exit: + /* Cleanup for path */ + path_cleanup(&path); + return return_value; } @@ -2412,7 +2432,7 @@ os_mkdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0, 0); int mode = 511; int dir_fd = DEFAULT_DIR_FD; @@ -2673,8 +2693,8 @@ os_rename(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0); - path_t dst = PATH_T_INITIALIZE("rename", "dst", 0, 0); + path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0, 0); + path_t dst = PATH_T_INITIALIZE("rename", "dst", 0, 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; @@ -2764,8 +2784,8 @@ os_replace(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE("replace", "src", 0, 0); - path_t dst = PATH_T_INITIALIZE("replace", "dst", 0, 0); + path_t src = PATH_T_INITIALIZE("replace", "src", 0, 0, 0); + path_t dst = PATH_T_INITIALIZE("replace", "dst", 0, 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; @@ -2853,7 +2873,7 @@ os_rmdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -3102,7 +3122,7 @@ os_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -3176,7 +3196,7 @@ os_remove(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("remove", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("remove", "path", 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -3294,7 +3314,7 @@ os_utime(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("utime", "path", 0, PATH_UTIME_HAVE_FD); + path_t path = PATH_T_INITIALIZE("utime", "path", 0, 0, PATH_UTIME_HAVE_FD); PyObject *times = Py_None; PyObject *ns = NULL; int dir_fd = DEFAULT_DIR_FD; @@ -3429,7 +3449,7 @@ static PyObject * os_execv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE("execv", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("execv", "path", 0, 0, 0); PyObject *argv; if (!_PyArg_CheckPositional("execv", nargs, 2, 2)) { @@ -3501,7 +3521,7 @@ os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[3]; - path_t path = PATH_T_INITIALIZE("execve", "path", 0, PATH_HAVE_FEXECVE); + path_t path = PATH_T_INITIALIZE("execve", "path", 0, 0, PATH_HAVE_FEXECVE); PyObject *argv; PyObject *env; @@ -3597,7 +3617,7 @@ os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #undef KWTUPLE PyObject *argsbuf[10]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE("posix_spawn", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("posix_spawn", "path", 0, 0, 0); PyObject *argv; PyObject *env; PyObject *file_actions = NULL; @@ -3747,7 +3767,7 @@ os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj #undef KWTUPLE PyObject *argsbuf[10]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE("posix_spawnp", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("posix_spawnp", "path", 0, 0, 0); PyObject *argv; PyObject *env; PyObject *file_actions = NULL; @@ -3851,7 +3871,7 @@ os_spawnv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; int mode; - path_t path = PATH_T_INITIALIZE("spawnv", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("spawnv", "path", 0, 0, 0); PyObject *argv; if (!_PyArg_CheckPositional("spawnv", nargs, 3, 3)) { @@ -3905,7 +3925,7 @@ os_spawnve(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; int mode; - path_t path = PATH_T_INITIALIZE("spawnve", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("spawnve", "path", 0, 0, 0); PyObject *argv; PyObject *env; @@ -6081,7 +6101,7 @@ os_readlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("readlink", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("readlink", "path", 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -6165,8 +6185,8 @@ os_symlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE("symlink", "src", 0, 0); - path_t dst = PATH_T_INITIALIZE("symlink", "dst", 0, 0); + path_t src = PATH_T_INITIALIZE("symlink", "src", 0, 0, 0); + path_t dst = PATH_T_INITIALIZE("symlink", "dst", 0, 0, 0); int target_is_directory = 0; int dir_fd = DEFAULT_DIR_FD; @@ -6808,7 +6828,7 @@ os_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("open", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("open", "path", 0, 0, 0); int flags; int mode = 511; int dir_fd = DEFAULT_DIR_FD; @@ -8396,7 +8416,7 @@ os_mkfifo(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0, 0); int mode = 438; int dir_fd = DEFAULT_DIR_FD; @@ -8496,7 +8516,7 @@ os_mknod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0, 0); int mode = 384; dev_t device = 0; int dir_fd = DEFAULT_DIR_FD; @@ -8750,7 +8770,7 @@ os_truncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject }; #undef KWTUPLE PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE("truncate", "path", 0, PATH_HAVE_FTRUNCATE); + path_t path = PATH_T_INITIALIZE("truncate", "path", 0, 0, PATH_HAVE_FTRUNCATE); Py_off_t length; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -9649,7 +9669,7 @@ os_statvfs(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, PATH_HAVE_FSTATVFS); + path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, 0, PATH_HAVE_FSTATVFS); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -9713,7 +9733,7 @@ os__getdiskusage(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_getdiskusage", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("_getdiskusage", "path", 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -9827,7 +9847,7 @@ os_pathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject }; #undef KWTUPLE PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, PATH_HAVE_FPATHCONF); + path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, 0, PATH_HAVE_FPATHCONF); int name; long _return_value; @@ -10017,10 +10037,10 @@ os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t filepath = PATH_T_INITIALIZE("startfile", "filepath", 0, 0); + path_t filepath = PATH_T_INITIALIZE("startfile", "filepath", 0, 0, 0); const wchar_t *operation = NULL; const wchar_t *arguments = NULL; - path_t cwd = PATH_T_INITIALIZE("startfile", "cwd", 1, 0); + path_t cwd = PATH_T_INITIALIZE("startfile", "cwd", 1, 0, 0); int show_cmd = 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 5, 0, argsbuf); @@ -10355,8 +10375,8 @@ os_getxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 1); - path_t attribute = PATH_T_INITIALIZE("getxattr", "attribute", 0, 0); + path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 0, 1); + path_t attribute = PATH_T_INITIALIZE("getxattr", "attribute", 0, 0, 0); int follow_symlinks = 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -10442,8 +10462,8 @@ os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE("setxattr", "path", 0, 1); - path_t attribute = PATH_T_INITIALIZE("setxattr", "attribute", 0, 0); + path_t path = PATH_T_INITIALIZE("setxattr", "path", 0, 0, 1); + path_t attribute = PATH_T_INITIALIZE("setxattr", "attribute", 0, 0, 0); Py_buffer value = {NULL, NULL}; int flags = 0; int follow_symlinks = 1; @@ -10550,8 +10570,8 @@ os_removexattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 1); - path_t attribute = PATH_T_INITIALIZE("removexattr", "attribute", 0, 0); + path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 0, 1); + path_t attribute = PATH_T_INITIALIZE("removexattr", "attribute", 0, 0, 0); int follow_symlinks = 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -10636,7 +10656,7 @@ os_listxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 1); + path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 0, 1); int follow_symlinks = 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); @@ -11613,7 +11633,7 @@ os_scandir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - path_t path = PATH_T_INITIALIZE("scandir", "path", 1, PATH_HAVE_FDOPENDIR); + path_t path = PATH_T_INITIALIZE("scandir", "path", 1, 0, PATH_HAVE_FDOPENDIR); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { @@ -11825,7 +11845,7 @@ os__add_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs, }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_add_dll_directory", "path", 0, 0); + path_t path = PATH_T_INITIALIZE("_add_dll_directory", "path", 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -12660,4 +12680,4 @@ os__supports_virtual_terminal(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF #define OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF #endif /* !defined(OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF) */ -/*[clinic end generated code: output=c4698b47007cd6eb input=a9049054013a1b77]*/ +/*[clinic end generated code: output=83770b03eff7f115 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index c9d67ccbb8c908..59cc7784268d29 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1108,6 +1108,8 @@ get_posix_state(PyObject *module) * Input fields: * path.nullable * If nonzero, the path is permitted to be None. + * path.null_embeddable + * If nonzero, the path is permitted to contain embedded null characters. * path.allow_fd * If nonzero, the path is permitted to be a file handle * (a signed int) instead of a string. @@ -1170,10 +1172,13 @@ get_posix_state(PyObject *module) * path_cleanup(). However it is safe to do so.) */ typedef struct { + // Input fields const char *function_name; const char *argument_name; int nullable; + int null_embeddable; int allow_fd; + // Output fields const wchar_t *wide; #ifdef MS_WINDOWS BOOL narrow; @@ -1187,11 +1192,11 @@ typedef struct { } path_t; #ifdef MS_WINDOWS -#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \ - {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL} +#define PATH_T_INITIALIZE(function_name, argument_name, nullable, null_embeddable, allow_fd) \ + {function_name, argument_name, nullable, null_embeddable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL} #else -#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \ - {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL} +#define PATH_T_INITIALIZE(function_name, argument_name, nullable, null_embeddable, allow_fd) \ + {function_name, argument_name, nullable, null_embeddable, allow_fd, NULL, NULL, -1, 0, NULL, NULL} #endif static void @@ -1293,7 +1298,7 @@ path_converter(PyObject *o, void *p) FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); goto error_exit; } - if (wcslen(wide) != length) { + if (!path->null_embeddable && wcslen(wide) != length) { FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); goto error_exit; } @@ -1304,7 +1309,7 @@ path_converter(PyObject *o, void *p) wide = NULL; goto success_exit; #else - if (!PyUnicode_FSConverter(o, &bytes)) { + if (!_PyUnicode_FSConverter(o, &bytes, path->null_embeddable)) { goto error_exit; } #endif @@ -1341,7 +1346,7 @@ path_converter(PyObject *o, void *p) length = PyBytes_GET_SIZE(bytes); narrow = PyBytes_AS_STRING(bytes); - if ((size_t)length != strlen(narrow)) { + if (!path->null_embeddable && (size_t)length != strlen(narrow)) { FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); goto error_exit; } @@ -1364,7 +1369,7 @@ path_converter(PyObject *o, void *p) FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); goto error_exit; } - if (wcslen(wide) != length) { + if (!path->null_embeddable && wcslen(wide) != length) { FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); goto error_exit; } @@ -2911,7 +2916,7 @@ class path_t_converter(CConverter): converter = 'path_converter' - def converter_init(self, *, allow_fd=False, nullable=False): + def converter_init(self, *, allow_fd=False, nullable=False, null_embeddable=False): # right now path_t doesn't support default values. # to support a default value, you'll need to override initialize(). if self.default not in (unspecified, None): @@ -2921,6 +2926,7 @@ class path_t_converter(CConverter): raise RuntimeError("Can't specify a c_default to the path_t converter!") self.nullable = nullable + self.null_embeddable = null_embeddable self.allow_fd = allow_fd def pre_render(self): @@ -2930,10 +2936,11 @@ class path_t_converter(CConverter): return str(int(bool(value))) # add self.py_name here when merging with posixmodule conversion - self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format( + self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {}, {})'.format( self.function.name, self.name, strify(self.nullable), + strify(self.null_embeddable), strify(self.allow_fd), ) @@ -3014,7 +3021,7 @@ class sysconf_confname_converter(path_confname_converter): converter="conv_sysconf_confname" [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=3338733161aa7879]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=f1a792e1921bd863]*/ /*[clinic input] @@ -5089,36 +5096,30 @@ os__path_splitroot_impl(PyObject *module, path_t *path) /*[clinic input] os._path_isdir - s: 'O' + s as path: path_t(null_embeddable=True, allow_fd=True) Return true if the pathname refers to an existing directory. [clinic start generated code]*/ static PyObject * -os__path_isdir_impl(PyObject *module, PyObject *s) -/*[clinic end generated code: output=9d87ab3c8b8a4e61 input=c17f7ef21d22d64e]*/ +os__path_isdir_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=0adeafd60704f710 input=ea7242408dd79e95]*/ { HANDLE hfile; BOOL close_file = TRUE; FILE_BASIC_INFO info; - path_t _path = PATH_T_INITIALIZE("isdir", "s", 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (!path_converter(s, &_path)) { - path_cleanup(&_path); - if (PyErr_ExceptionMatches(PyExc_ValueError)) { - PyErr_Clear(); - Py_RETURN_FALSE; - } - return NULL; + if (path->wide && wcslen(path->wide) != path->length) { + Py_RETURN_FALSE; } Py_BEGIN_ALLOW_THREADS - if (_path.wide) { - if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo, + if (path->wide) { + if (_Py_GetFileInformationByName(path->wide, FileStatBasicByNameInfo, &statInfo, sizeof(statInfo))) { if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { slow_path = FALSE; @@ -5133,12 +5134,12 @@ os__path_isdir_impl(PyObject *module, PyObject *s) } } if (slow_path) { - if (_path.fd != -1) { - hfile = _Py_get_osfhandle_noraise(_path.fd); + if (path->fd != -1) { + hfile = _Py_get_osfhandle_noraise(path->fd); close_file = FALSE; } else { - hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL, + hfile = CreateFileW(path->wide, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); } if (hfile != INVALID_HANDLE_VALUE) { @@ -5161,7 +5162,7 @@ os__path_isdir_impl(PyObject *module, PyObject *s) case ERROR_SHARING_VIOLATION: case ERROR_CANT_ACCESS_FILE: case ERROR_INVALID_PARAMETER: - if (STAT(_path.wide, &st)) { + if (STAT(path->wide, &st)) { result = 0; } else { @@ -5175,7 +5176,6 @@ os__path_isdir_impl(PyObject *module, PyObject *s) } Py_END_ALLOW_THREADS - path_cleanup(&_path); if (result) { Py_RETURN_TRUE; } @@ -5186,36 +5186,30 @@ os__path_isdir_impl(PyObject *module, PyObject *s) /*[clinic input] os._path_isfile - path: 'O' + path: path_t(null_embeddable=True, allow_fd=True) Test whether a path is a regular file [clinic start generated code]*/ static PyObject * -os__path_isfile_impl(PyObject *module, PyObject *path) -/*[clinic end generated code: output=2394ed7c4b5cfd85 input=de22d74960ade365]*/ +os__path_isfile_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=4f72e7b1ada002da input=4ab9dca4fbc441b1]*/ { HANDLE hfile; BOOL close_file = TRUE; FILE_BASIC_INFO info; - path_t _path = PATH_T_INITIALIZE("isfile", "path", 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (!path_converter(path, &_path)) { - path_cleanup(&_path); - if (PyErr_ExceptionMatches(PyExc_ValueError)) { - PyErr_Clear(); - Py_RETURN_FALSE; - } - return NULL; + if (path->wide && wcslen(path->wide) != path->length) { + Py_RETURN_FALSE; } Py_BEGIN_ALLOW_THREADS - if (_path.wide) { - if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo, + if (path->wide) { + if (_Py_GetFileInformationByName(path->wide, FileStatBasicByNameInfo, &statInfo, sizeof(statInfo))) { if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { slow_path = FALSE; @@ -5230,12 +5224,12 @@ os__path_isfile_impl(PyObject *module, PyObject *path) } } if (slow_path) { - if (_path.fd != -1) { - hfile = _Py_get_osfhandle_noraise(_path.fd); + if (path->fd != -1) { + hfile = _Py_get_osfhandle_noraise(path->fd); close_file = FALSE; } else { - hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL, + hfile = CreateFileW(path->wide, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); } if (hfile != INVALID_HANDLE_VALUE) { @@ -5258,7 +5252,7 @@ os__path_isfile_impl(PyObject *module, PyObject *path) case ERROR_SHARING_VIOLATION: case ERROR_CANT_ACCESS_FILE: case ERROR_INVALID_PARAMETER: - if (STAT(_path.wide, &st)) { + if (STAT(path->wide, &st)) { result = 0; } else { @@ -5272,7 +5266,6 @@ os__path_isfile_impl(PyObject *module, PyObject *path) } Py_END_ALLOW_THREADS - path_cleanup(&_path); if (result) { Py_RETURN_TRUE; } @@ -5283,35 +5276,29 @@ os__path_isfile_impl(PyObject *module, PyObject *path) /*[clinic input] os._path_exists - path: 'O' + path: path_t(null_embeddable=True, allow_fd=True) Test whether a path exists. Returns False for broken symbolic links [clinic start generated code]*/ static PyObject * -os__path_exists_impl(PyObject *module, PyObject *path) -/*[clinic end generated code: output=f508c3b35e13a249 input=380f77cdfa0f7ae8]*/ +os__path_exists_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=69e6089df1fe463a input=bfd8cf0f7e09722f]*/ { HANDLE hfile; BOOL close_file = TRUE; - path_t _path = PATH_T_INITIALIZE("exists", "path", 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (!path_converter(path, &_path)) { - path_cleanup(&_path); - if (PyErr_ExceptionMatches(PyExc_ValueError)) { - PyErr_Clear(); - Py_RETURN_FALSE; - } - return NULL; + if (path->wide && wcslen(path->wide) != path->length) { + Py_RETURN_FALSE; } Py_BEGIN_ALLOW_THREADS - if (_path.wide) { - if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo, + if (path->wide) { + if (_Py_GetFileInformationByName(path->wide, FileStatBasicByNameInfo, &statInfo, sizeof(statInfo))) { if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { slow_path = FALSE; @@ -5323,12 +5310,12 @@ os__path_exists_impl(PyObject *module, PyObject *path) } } if (slow_path) { - if (_path.fd != -1) { - hfile = _Py_get_osfhandle_noraise(_path.fd); + if (path->fd != -1) { + hfile = _Py_get_osfhandle_noraise(path->fd); close_file = FALSE; } else { - hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL, + hfile = CreateFileW(path->wide, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); } if (hfile != INVALID_HANDLE_VALUE) { @@ -5344,7 +5331,7 @@ os__path_exists_impl(PyObject *module, PyObject *path) case ERROR_SHARING_VIOLATION: case ERROR_CANT_ACCESS_FILE: case ERROR_INVALID_PARAMETER: - if (STAT(_path.wide, &st)) { + if (STAT(path->wide, &st)) { result = 0; } else { @@ -5358,7 +5345,6 @@ os__path_exists_impl(PyObject *module, PyObject *path) } Py_END_ALLOW_THREADS - path_cleanup(&_path); if (result) { Py_RETURN_TRUE; } @@ -5369,36 +5355,30 @@ os__path_exists_impl(PyObject *module, PyObject *path) /*[clinic input] os._path_islink - path: 'O' + path: path_t(null_embeddable=True, allow_fd=True) Test whether a path is a symbolic link [clinic start generated code]*/ static PyObject * -os__path_islink_impl(PyObject *module, PyObject *path) -/*[clinic end generated code: output=6d8640b1a390c054 input=38a3cb937ccf59bf]*/ +os__path_islink_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=109ad77ec747b3b7 input=380264532e0862a3]*/ { HANDLE hfile; BOOL close_file = TRUE; FILE_ATTRIBUTE_TAG_INFO info; - path_t _path = PATH_T_INITIALIZE("islink", "path", 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (!path_converter(path, &_path)) { - path_cleanup(&_path); - if (PyErr_ExceptionMatches(PyExc_ValueError)) { - PyErr_Clear(); - Py_RETURN_FALSE; - } - return NULL; + if (path->wide && wcslen(path->wide) != path->length) { + Py_RETURN_FALSE; } Py_BEGIN_ALLOW_THREADS - if (_path.wide) { - if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo, + if (path->wide) { + if (_Py_GetFileInformationByName(path->wide, FileStatBasicByNameInfo, &statInfo, sizeof(statInfo))) { slow_path = FALSE; if (statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { @@ -5413,12 +5393,12 @@ os__path_islink_impl(PyObject *module, PyObject *path) } } if (slow_path) { - if (_path.fd != -1) { - hfile = _Py_get_osfhandle_noraise(_path.fd); + if (path->fd != -1) { + hfile = _Py_get_osfhandle_noraise(path->fd); close_file = FALSE; } else { - hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL, + hfile = CreateFileW(path->wide, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); @@ -5443,7 +5423,7 @@ os__path_islink_impl(PyObject *module, PyObject *path) case ERROR_SHARING_VIOLATION: case ERROR_CANT_ACCESS_FILE: case ERROR_INVALID_PARAMETER: - if (LSTAT(_path.wide, &st)) { + if (LSTAT(path->wide, &st)) { result = 0; } else { @@ -5457,7 +5437,6 @@ os__path_islink_impl(PyObject *module, PyObject *path) } Py_END_ALLOW_THREADS - path_cleanup(&_path); if (result) { Py_RETURN_TRUE; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 2c259b7e869efe..d100376bdb136c 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3790,7 +3790,7 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) int -PyUnicode_FSConverter(PyObject* arg, void* addr) +_PyUnicode_FSConverter(PyObject* arg, void* addr, int null_embeddable) { PyObject *path = NULL; PyObject *output = NULL; @@ -3819,7 +3819,7 @@ PyUnicode_FSConverter(PyObject* arg, void* addr) size = PyBytes_GET_SIZE(output); data = PyBytes_AS_STRING(output); - if ((size_t)size != strlen(data)) { + if (!null_embeddable && (size_t)size != strlen(data)) { PyErr_SetString(PyExc_ValueError, "embedded null byte"); Py_DECREF(output); return 0; @@ -3828,6 +3828,12 @@ PyUnicode_FSConverter(PyObject* arg, void* addr) return Py_CLEANUP_SUPPORTED; } +int +PyUnicode_FSConverter(PyObject* arg, void* addr) +{ + return _PyUnicode_FSConverter(arg, addr, 0); +} + int PyUnicode_FSDecoder(PyObject* arg, void* addr) From 0625bf1785bf218a91ff77e9369483d04c42a530 Mon Sep 17 00:00:00 2001 From: nineteendo Date: Sun, 28 Apr 2024 21:48:57 +0200 Subject: [PATCH 02/26] Add `make_wide` --- Lib/ntpath.py | 28 +-- Lib/posixpath.py | 28 +-- Modules/clinic/posixmodule.c.h | 201 ++++++++++----------- Modules/posixmodule.c | 319 +++++++++++++++++++-------------- 4 files changed, 286 insertions(+), 290 deletions(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py index e810b655e5ac85..9375b05d7027ee 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -168,7 +168,7 @@ def splitdrive(p): try: - from nt import _path_splitroot_ex + from nt import _path_splitroot_ex as splitroot except ImportError: def splitroot(p): """Split a pathname into drive, root and tail. The drive is defined @@ -220,23 +220,7 @@ def splitroot(p): else: # Relative path, e.g. Windows return empty, empty, p -else: - def splitroot(p): - """Split a pathname into drive, root and tail. The drive is defined - exactly as in splitdrive(). On Windows, the root may be a single path - separator or an empty string. The tail contains anything after the root. - For example: - splitroot('//server/share/') == ('//server/share', '/', '') - splitroot('C:/Users/Barney') == ('C:', '/', 'Users/Barney') - splitroot('C:///spam///ham') == ('C:', '/', '//spam///ham') - splitroot('Windows/notepad') == ('', '', 'Windows/notepad') - """ - p = os.fspath(p) - if isinstance(p, bytes): - drive, root, tail = _path_splitroot_ex(os.fsdecode(p)) - return os.fsencode(drive), os.fsencode(root), os.fsencode(tail) - return _path_splitroot_ex(p) # Split a path in head (everything up to the last '/') and tail (the @@ -553,7 +537,7 @@ def expandvars(path): # Previously, this function also truncated pathnames to 8+3 format, # but as this module is called "ntpath", that's obviously wrong! try: - from nt import _path_normpath + from nt import _path_normpath as normpath except ImportError: def normpath(path): @@ -592,14 +576,6 @@ def normpath(path): comps.append(curdir) return prefix + sep.join(comps) -else: - def normpath(path): - """Normalize path, eliminating double slashes, etc.""" - path = os.fspath(path) - if isinstance(path, bytes): - return os.fsencode(_path_normpath(os.fsdecode(path))) or b"." - return _path_normpath(path) or "." - def _abspath_fallback(path): """Return the absolute version of a path as a fallback function in case diff --git a/Lib/posixpath.py b/Lib/posixpath.py index 56b7915826daf4..bad1746ccb4f19 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -135,7 +135,7 @@ def splitdrive(p): try: - from posix import _path_splitroot_ex + from posix import _path_splitroot_ex as splitroot except ImportError: def splitroot(p): """Split a pathname into drive, root and tail. On Posix, drive is always @@ -164,23 +164,7 @@ def splitroot(p): # Precisely two leading slashes, e.g.: '//foo'. Implementation defined per POSIX, see # https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13 return empty, p[:2], p[2:] -else: - def splitroot(p): - """Split a pathname into drive, root and tail. On Posix, drive is always - empty; the root may be empty, a single slash, or two slashes. The tail - contains anything after the root. For example: - splitroot('foo/bar') == ('', '', 'foo/bar') - splitroot('/foo/bar') == ('', '/', 'foo/bar') - splitroot('//foo/bar') == ('', '//', 'foo/bar') - splitroot('///foo/bar') == ('', '/', '//foo/bar') - """ - p = os.fspath(p) - if isinstance(p, bytes): - # Optimisation: the drive is always empty - _, root, tail = _path_splitroot_ex(os.fsdecode(p)) - return b'', os.fsencode(root), os.fsencode(tail) - return _path_splitroot_ex(p) # Return the tail (basename) part of a path, same as split(path)[1]. @@ -366,7 +350,7 @@ def expandvars(path): # if it contains symbolic links! try: - from posix import _path_normpath + from posix import _path_normpath as normpath except ImportError: def normpath(path): @@ -397,14 +381,6 @@ def normpath(path): path = initial_slashes + sep.join(comps) return path or dot -else: - def normpath(path): - """Normalize path, eliminating double slashes, etc.""" - path = os.fspath(path) - if isinstance(path, bytes): - return os.fsencode(_path_normpath(os.fsdecode(path))) or b"." - return _path_normpath(path) or "." - def abspath(path): """Return an absolute path.""" diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index b6a582f6e81cfa..5015e65b6f2e2a 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -72,7 +72,7 @@ os_stat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("stat", "path", 0, 0, 1); + path_t path = PATH_T_INITIALIZE("stat", "path", 0, 0, 0, 1); int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; @@ -154,7 +154,7 @@ os_lstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -250,7 +250,7 @@ os_access(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("access", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("access", "path", 0, 0, 0, 0); int mode; int dir_fd = DEFAULT_DIR_FD; int effective_ids = 0; @@ -409,7 +409,7 @@ os_chdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("chdir", "path", 0, 0, PATH_HAVE_FCHDIR); + path_t path = PATH_T_INITIALIZE("chdir", "path", 0, 0, 0, PATH_HAVE_FCHDIR); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -560,7 +560,7 @@ os_chmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("chmod", "path", 0, 0, PATH_HAVE_FCHMOD); + path_t path = PATH_T_INITIALIZE("chmod", "path", 0, 0, 0, PATH_HAVE_FCHMOD); int mode; int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = CHMOD_DEFAULT_FOLLOW_SYMLINKS; @@ -725,7 +725,7 @@ os_lchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0, 0, 0); int mode; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -802,7 +802,7 @@ os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0, 0, 0); unsigned long flags; int follow_symlinks = 1; @@ -884,7 +884,7 @@ os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject }; #undef KWTUPLE PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0, 0, 0); unsigned long flags; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -954,7 +954,7 @@ os_chroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -1190,7 +1190,7 @@ os_chown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE("chown", "path", 0, 0, PATH_HAVE_FCHOWN); + path_t path = PATH_T_INITIALIZE("chown", "path", 0, 0, 0, PATH_HAVE_FCHOWN); uid_t uid; gid_t gid; int dir_fd = DEFAULT_DIR_FD; @@ -1355,7 +1355,7 @@ os_lchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[3]; - path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0, 0, 0); uid_t uid; gid_t gid; @@ -1476,8 +1476,8 @@ os_link(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE("link", "src", 0, 0, 0); - path_t dst = PATH_T_INITIALIZE("link", "dst", 0, 0, 0); + path_t src = PATH_T_INITIALIZE("link", "src", 0, 0, 0, 0); + path_t dst = PATH_T_INITIALIZE("link", "dst", 0, 0, 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; @@ -1583,7 +1583,7 @@ os_listdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - path_t path = PATH_T_INITIALIZE("listdir", "path", 1, 0, PATH_HAVE_FDOPENDIR); + path_t path = PATH_T_INITIALIZE("listdir", "path", 1, 0, 0, PATH_HAVE_FDOPENDIR); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { @@ -1699,7 +1699,7 @@ os_listmounts(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t volume = PATH_T_INITIALIZE("listmounts", "volume", 0, 0, 0); + path_t volume = PATH_T_INITIALIZE("listmounts", "volume", 0, 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -1763,7 +1763,7 @@ os__path_isdevdrive(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_path_isdevdrive", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("_path_isdevdrive", "path", 0, 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -1800,7 +1800,7 @@ static PyObject * os__getfullpathname(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE("_getfullpathname", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("_getfullpathname", "path", 0, 0, 0, 0); if (!path_converter(arg, &path)) { goto exit; @@ -1834,7 +1834,7 @@ static PyObject * os__getfinalpathname(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE("_getfinalpathname", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("_getfinalpathname", "path", 0, 0, 0, 0); if (!path_converter(arg, &path)) { goto exit; @@ -1868,7 +1868,7 @@ static PyObject * os__findfirstfile(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE("_findfirstfile", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("_findfirstfile", "path", 0, 0, 0, 0); if (!path_converter(arg, &path)) { goto exit; @@ -1928,7 +1928,7 @@ os__getvolumepathname(PyObject *module, PyObject *const *args, Py_ssize_t nargs, }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_getvolumepathname", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("_getvolumepathname", "path", 0, 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -1992,7 +1992,7 @@ os__path_splitroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_path_splitroot", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("_path_splitroot", "path", 0, 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -2024,7 +2024,7 @@ PyDoc_STRVAR(os__path_isdir__doc__, {"_path_isdir", _PyCFunction_CAST(os__path_isdir), METH_FASTCALL|METH_KEYWORDS, os__path_isdir__doc__}, static PyObject * -os__path_isdir_impl(PyObject *module, path_t *path); +os__path_isdir_impl(PyObject *module, PyObject *s); static PyObject * os__path_isdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -2056,21 +2056,16 @@ os__path_isdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_path_isdir", "path", 0, 1, 1); + PyObject *s; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - if (!path_converter(args[0], &path)) { - goto exit; - } - return_value = os__path_isdir_impl(module, &path); + s = args[0]; + return_value = os__path_isdir_impl(module, s); exit: - /* Cleanup for path */ - path_cleanup(&path); - return return_value; } @@ -2088,7 +2083,7 @@ PyDoc_STRVAR(os__path_isfile__doc__, {"_path_isfile", _PyCFunction_CAST(os__path_isfile), METH_FASTCALL|METH_KEYWORDS, os__path_isfile__doc__}, static PyObject * -os__path_isfile_impl(PyObject *module, path_t *path); +os__path_isfile_impl(PyObject *module, PyObject *path); static PyObject * os__path_isfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -2120,21 +2115,16 @@ os__path_isfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_path_isfile", "path", 0, 1, 1); + PyObject *path; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - if (!path_converter(args[0], &path)) { - goto exit; - } - return_value = os__path_isfile_impl(module, &path); + path = args[0]; + return_value = os__path_isfile_impl(module, path); exit: - /* Cleanup for path */ - path_cleanup(&path); - return return_value; } @@ -2152,7 +2142,7 @@ PyDoc_STRVAR(os__path_exists__doc__, {"_path_exists", _PyCFunction_CAST(os__path_exists), METH_FASTCALL|METH_KEYWORDS, os__path_exists__doc__}, static PyObject * -os__path_exists_impl(PyObject *module, path_t *path); +os__path_exists_impl(PyObject *module, PyObject *path); static PyObject * os__path_exists(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -2184,21 +2174,16 @@ os__path_exists(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_path_exists", "path", 0, 1, 1); + PyObject *path; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - if (!path_converter(args[0], &path)) { - goto exit; - } - return_value = os__path_exists_impl(module, &path); + path = args[0]; + return_value = os__path_exists_impl(module, path); exit: - /* Cleanup for path */ - path_cleanup(&path); - return return_value; } @@ -2216,7 +2201,7 @@ PyDoc_STRVAR(os__path_islink__doc__, {"_path_islink", _PyCFunction_CAST(os__path_islink), METH_FASTCALL|METH_KEYWORDS, os__path_islink__doc__}, static PyObject * -os__path_islink_impl(PyObject *module, path_t *path); +os__path_islink_impl(PyObject *module, PyObject *path); static PyObject * os__path_islink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -2248,21 +2233,16 @@ os__path_islink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_path_islink", "path", 0, 1, 1); + PyObject *path; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - if (!path_converter(args[0], &path)) { - goto exit; - } - return_value = os__path_islink_impl(module, &path); + path = args[0]; + return_value = os__path_islink_impl(module, path); exit: - /* Cleanup for path */ - path_cleanup(&path); - return return_value; } @@ -2271,13 +2251,16 @@ os__path_islink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj PyDoc_STRVAR(os__path_splitroot_ex__doc__, "_path_splitroot_ex($module, /, path)\n" "--\n" -"\n"); +"\n" +"Split a pathname into drive, root and tail.\n" +"\n" +"The tail contains anything after the root."); #define OS__PATH_SPLITROOT_EX_METHODDEF \ {"_path_splitroot_ex", _PyCFunction_CAST(os__path_splitroot_ex), METH_FASTCALL|METH_KEYWORDS, os__path_splitroot_ex__doc__}, static PyObject * -os__path_splitroot_ex_impl(PyObject *module, PyObject *path); +os__path_splitroot_ex_impl(PyObject *module, path_t *path); static PyObject * os__path_splitroot_ex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -2309,20 +2292,21 @@ os__path_splitroot_ex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *path; + path_t path = PATH_T_INITIALIZE("_path_splitroot_ex", "path", 0, 1, 1, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("_path_splitroot_ex", "argument 'path'", "str", args[0]); + if (!path_converter(args[0], &path)) { goto exit; } - path = args[0]; - return_value = os__path_splitroot_ex_impl(module, path); + return_value = os__path_splitroot_ex_impl(module, &path); exit: + /* Cleanup for path */ + path_cleanup(&path); + return return_value; } @@ -2330,13 +2314,13 @@ PyDoc_STRVAR(os__path_normpath__doc__, "_path_normpath($module, /, path)\n" "--\n" "\n" -"Basic path normalization."); +"Normalize path, eliminating double slashes, etc."); #define OS__PATH_NORMPATH_METHODDEF \ {"_path_normpath", _PyCFunction_CAST(os__path_normpath), METH_FASTCALL|METH_KEYWORDS, os__path_normpath__doc__}, static PyObject * -os__path_normpath_impl(PyObject *module, PyObject *path); +os__path_normpath_impl(PyObject *module, path_t *path); static PyObject * os__path_normpath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -2368,16 +2352,21 @@ os__path_normpath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *path; + path_t path = PATH_T_INITIALIZE("_path_normpath", "path", 0, 1, 1, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - path = args[0]; - return_value = os__path_normpath_impl(module, path); + if (!path_converter(args[0], &path)) { + goto exit; + } + return_value = os__path_normpath_impl(module, &path); exit: + /* Cleanup for path */ + path_cleanup(&path); + return return_value; } @@ -2432,7 +2421,7 @@ os_mkdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0, 0, 0); int mode = 511; int dir_fd = DEFAULT_DIR_FD; @@ -2693,8 +2682,8 @@ os_rename(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0, 0); - path_t dst = PATH_T_INITIALIZE("rename", "dst", 0, 0, 0); + path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0, 0, 0); + path_t dst = PATH_T_INITIALIZE("rename", "dst", 0, 0, 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; @@ -2784,8 +2773,8 @@ os_replace(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE("replace", "src", 0, 0, 0); - path_t dst = PATH_T_INITIALIZE("replace", "dst", 0, 0, 0); + path_t src = PATH_T_INITIALIZE("replace", "src", 0, 0, 0, 0); + path_t dst = PATH_T_INITIALIZE("replace", "dst", 0, 0, 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; @@ -2873,7 +2862,7 @@ os_rmdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -3122,7 +3111,7 @@ os_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -3196,7 +3185,7 @@ os_remove(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("remove", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("remove", "path", 0, 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -3314,7 +3303,7 @@ os_utime(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("utime", "path", 0, 0, PATH_UTIME_HAVE_FD); + path_t path = PATH_T_INITIALIZE("utime", "path", 0, 0, 0, PATH_UTIME_HAVE_FD); PyObject *times = Py_None; PyObject *ns = NULL; int dir_fd = DEFAULT_DIR_FD; @@ -3449,7 +3438,7 @@ static PyObject * os_execv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE("execv", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("execv", "path", 0, 0, 0, 0); PyObject *argv; if (!_PyArg_CheckPositional("execv", nargs, 2, 2)) { @@ -3521,7 +3510,7 @@ os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[3]; - path_t path = PATH_T_INITIALIZE("execve", "path", 0, 0, PATH_HAVE_FEXECVE); + path_t path = PATH_T_INITIALIZE("execve", "path", 0, 0, 0, PATH_HAVE_FEXECVE); PyObject *argv; PyObject *env; @@ -3617,7 +3606,7 @@ os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #undef KWTUPLE PyObject *argsbuf[10]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE("posix_spawn", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("posix_spawn", "path", 0, 0, 0, 0); PyObject *argv; PyObject *env; PyObject *file_actions = NULL; @@ -3767,7 +3756,7 @@ os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj #undef KWTUPLE PyObject *argsbuf[10]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE("posix_spawnp", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("posix_spawnp", "path", 0, 0, 0, 0); PyObject *argv; PyObject *env; PyObject *file_actions = NULL; @@ -3871,7 +3860,7 @@ os_spawnv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; int mode; - path_t path = PATH_T_INITIALIZE("spawnv", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("spawnv", "path", 0, 0, 0, 0); PyObject *argv; if (!_PyArg_CheckPositional("spawnv", nargs, 3, 3)) { @@ -3925,7 +3914,7 @@ os_spawnve(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; int mode; - path_t path = PATH_T_INITIALIZE("spawnve", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("spawnve", "path", 0, 0, 0, 0); PyObject *argv; PyObject *env; @@ -6101,7 +6090,7 @@ os_readlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("readlink", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("readlink", "path", 0, 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -6185,8 +6174,8 @@ os_symlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE("symlink", "src", 0, 0, 0); - path_t dst = PATH_T_INITIALIZE("symlink", "dst", 0, 0, 0); + path_t src = PATH_T_INITIALIZE("symlink", "src", 0, 0, 0, 0); + path_t dst = PATH_T_INITIALIZE("symlink", "dst", 0, 0, 0, 0); int target_is_directory = 0; int dir_fd = DEFAULT_DIR_FD; @@ -6828,7 +6817,7 @@ os_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("open", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("open", "path", 0, 0, 0, 0); int flags; int mode = 511; int dir_fd = DEFAULT_DIR_FD; @@ -8416,7 +8405,7 @@ os_mkfifo(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0, 0, 0); int mode = 438; int dir_fd = DEFAULT_DIR_FD; @@ -8516,7 +8505,7 @@ os_mknod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0, 0, 0); int mode = 384; dev_t device = 0; int dir_fd = DEFAULT_DIR_FD; @@ -8770,7 +8759,7 @@ os_truncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject }; #undef KWTUPLE PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE("truncate", "path", 0, 0, PATH_HAVE_FTRUNCATE); + path_t path = PATH_T_INITIALIZE("truncate", "path", 0, 0, 0, PATH_HAVE_FTRUNCATE); Py_off_t length; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -9669,7 +9658,7 @@ os_statvfs(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, 0, PATH_HAVE_FSTATVFS); + path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, 0, 0, PATH_HAVE_FSTATVFS); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -9733,7 +9722,7 @@ os__getdiskusage(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_getdiskusage", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("_getdiskusage", "path", 0, 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -9847,7 +9836,7 @@ os_pathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject }; #undef KWTUPLE PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, 0, PATH_HAVE_FPATHCONF); + path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, 0, 0, PATH_HAVE_FPATHCONF); int name; long _return_value; @@ -10037,10 +10026,10 @@ os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t filepath = PATH_T_INITIALIZE("startfile", "filepath", 0, 0, 0); + path_t filepath = PATH_T_INITIALIZE("startfile", "filepath", 0, 0, 0, 0); const wchar_t *operation = NULL; const wchar_t *arguments = NULL; - path_t cwd = PATH_T_INITIALIZE("startfile", "cwd", 1, 0, 0); + path_t cwd = PATH_T_INITIALIZE("startfile", "cwd", 1, 0, 0, 0); int show_cmd = 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 5, 0, argsbuf); @@ -10375,8 +10364,8 @@ os_getxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 0, 1); - path_t attribute = PATH_T_INITIALIZE("getxattr", "attribute", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 0, 0, 1); + path_t attribute = PATH_T_INITIALIZE("getxattr", "attribute", 0, 0, 0, 0); int follow_symlinks = 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -10462,8 +10451,8 @@ os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE("setxattr", "path", 0, 0, 1); - path_t attribute = PATH_T_INITIALIZE("setxattr", "attribute", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("setxattr", "path", 0, 0, 0, 1); + path_t attribute = PATH_T_INITIALIZE("setxattr", "attribute", 0, 0, 0, 0); Py_buffer value = {NULL, NULL}; int flags = 0; int follow_symlinks = 1; @@ -10570,8 +10559,8 @@ os_removexattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 0, 1); - path_t attribute = PATH_T_INITIALIZE("removexattr", "attribute", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 0, 0, 1); + path_t attribute = PATH_T_INITIALIZE("removexattr", "attribute", 0, 0, 0, 0); int follow_symlinks = 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -10656,7 +10645,7 @@ os_listxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 0, 1); + path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 0, 0, 1); int follow_symlinks = 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); @@ -11633,7 +11622,7 @@ os_scandir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - path_t path = PATH_T_INITIALIZE("scandir", "path", 1, 0, PATH_HAVE_FDOPENDIR); + path_t path = PATH_T_INITIALIZE("scandir", "path", 1, 0, 0, PATH_HAVE_FDOPENDIR); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { @@ -11845,7 +11834,7 @@ os__add_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs, }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_add_dll_directory", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE("_add_dll_directory", "path", 0, 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -12680,4 +12669,4 @@ os__supports_virtual_terminal(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF #define OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF #endif /* !defined(OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF) */ -/*[clinic end generated code: output=83770b03eff7f115 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bfd2d2216e6079a8 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 59cc7784268d29..69db201b64b2d9 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1110,6 +1110,8 @@ get_posix_state(PyObject *module) * If nonzero, the path is permitted to be None. * path.null_embeddable * If nonzero, the path is permitted to contain embedded null characters. + * path.make_wide + * If zero, the path is encoded to bytes. (Argument is ignored on Windows) * path.allow_fd * If nonzero, the path is permitted to be a file handle * (a signed int) instead of a string. @@ -1125,7 +1127,7 @@ get_posix_state(PyObject *module) * Output fields: * path.wide * Points to the path if it was expressed as Unicode - * and was not encoded. (Only used on Windows.) + * and was not encoded. * path.narrow * Points to the path if it was expressed as bytes, * or it was Unicode and was encoded to bytes. (On Windows, @@ -1177,6 +1179,7 @@ typedef struct { const char *argument_name; int nullable; int null_embeddable; + int make_wide; int allow_fd; // Output fields const wchar_t *wide; @@ -1192,11 +1195,15 @@ typedef struct { } path_t; #ifdef MS_WINDOWS -#define PATH_T_INITIALIZE(function_name, argument_name, nullable, null_embeddable, allow_fd) \ - {function_name, argument_name, nullable, null_embeddable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL} +#define PATH_T_INITIALIZE(function_name, argument_name, nullable, \ + null_embeddable, make_wide, allow_fd) \ + {function_name, argument_name, nullable, null_embeddable, make_wide, \ + allow_fd, NULL, FALSE, -1, 0, NULL, NULL} #else -#define PATH_T_INITIALIZE(function_name, argument_name, nullable, null_embeddable, allow_fd) \ - {function_name, argument_name, nullable, null_embeddable, allow_fd, NULL, NULL, -1, 0, NULL, NULL} +#define PATH_T_INITIALIZE(function_name, argument_name, nullable, \ + null_embeddable, make_wide, allow_fd) \ + {function_name, argument_name, nullable, null_embeddable, make_wide, \ + allow_fd, NULL, NULL, -1, 0, NULL, NULL} #endif static void @@ -1217,10 +1224,8 @@ path_converter(PyObject *o, void *p) Py_ssize_t length = 0; int is_index, is_bytes, is_unicode; const char *narrow; -#ifdef MS_WINDOWS PyObject *wo = NULL; wchar_t *wide = NULL; -#endif #define FORMAT_EXCEPTION(exc, fmt) \ PyErr_Format(exc, "%s%s" fmt, \ @@ -1289,26 +1294,36 @@ path_converter(PyObject *o, void *p) } if (is_unicode) { +#ifndef MS_WINDOWS + if (path->make_wide) { +#endif + wide = PyUnicode_AsWideCharString(o, &length); + if (!wide) { + goto error_exit; + } #ifdef MS_WINDOWS - wide = PyUnicode_AsWideCharString(o, &length); - if (!wide) { - goto error_exit; - } - if (length > 32767) { - FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); - goto error_exit; - } - if (!path->null_embeddable && wcslen(wide) != length) { - FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); - goto error_exit; - } + if (length > 32767) { + FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); + goto error_exit; + } +#endif + if (!path->null_embeddable && wcslen(wide) != length) { + FORMAT_EXCEPTION(PyExc_ValueError, + "embedded null character in %s"); + goto error_exit; + } - path->wide = wide; - path->narrow = FALSE; - path->fd = -1; - wide = NULL; - goto success_exit; + path->wide = wide; +#ifdef MS_WINDOWS + path->narrow = FALSE; #else + path->narrow = NULL; +#endif + path->fd = -1; + wide = NULL; + goto success_exit; +#ifndef MS_WINDOWS + } if (!_PyUnicode_FSConverter(o, &bytes, path->null_embeddable)) { goto error_exit; } @@ -1351,42 +1366,51 @@ path_converter(PyObject *o, void *p) goto error_exit; } -#ifdef MS_WINDOWS - wo = PyUnicode_DecodeFSDefaultAndSize( - narrow, - length - ); - if (!wo) { - goto error_exit; - } +#ifndef MS_WINDOWS + if (path->make_wide) { +#endif + wo = PyUnicode_DecodeFSDefaultAndSize(narrow, length); + if (!wo) { + goto error_exit; + } - wide = PyUnicode_AsWideCharString(wo, &length); - Py_DECREF(wo); - if (!wide) { - goto error_exit; - } - if (length > 32767) { - FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); - goto error_exit; - } - if (!path->null_embeddable && wcslen(wide) != length) { - FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); - goto error_exit; - } - path->wide = wide; - path->narrow = TRUE; - Py_DECREF(bytes); - wide = NULL; + wide = PyUnicode_AsWideCharString(wo, &length); + Py_DECREF(wo); + if (!wide) { + goto error_exit; + } +#ifdef MS_WINDOWS + if (length > 32767) { + FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); + goto error_exit; + } +#endif + if (!path->null_embeddable && wcslen(wide) != length) { + FORMAT_EXCEPTION(PyExc_ValueError, + "embedded null character in %s"); + goto error_exit; + } + path->wide = wide; +#ifdef MS_WINDOWS + path->narrow = TRUE; #else - path->wide = NULL; - path->narrow = narrow; - if (bytes == o) { - /* Still a reference owned by path->object, don't have to - worry about path->narrow is used after free. */ + path->narrow = narrow +#endif Py_DECREF(bytes); + wide = NULL; +#ifndef MS_WINDOWS } else { - path->cleanup = bytes; + path->wide = NULL; + path->narrow = narrow; + if (bytes == o) { + /* Still a reference owned by path->object, don't have to + worry about path->narrow is used after free. */ + Py_DECREF(bytes); + } + else { + path->cleanup = bytes; + } } #endif path->fd = -1; @@ -1399,9 +1423,7 @@ path_converter(PyObject *o, void *p) error_exit: Py_XDECREF(o); Py_XDECREF(bytes); -#ifdef MS_WINDOWS PyMem_Free(wide); -#endif return 0; } @@ -2916,7 +2938,8 @@ class path_t_converter(CConverter): converter = 'path_converter' - def converter_init(self, *, allow_fd=False, nullable=False, null_embeddable=False): + def converter_init(self, *, allow_fd=False, make_wide=False, + nullable=False, null_embeddable=False): # right now path_t doesn't support default values. # to support a default value, you'll need to override initialize(). if self.default not in (unspecified, None): @@ -2927,6 +2950,7 @@ class path_t_converter(CConverter): self.nullable = nullable self.null_embeddable = null_embeddable + self.make_wide = make_wide self.allow_fd = allow_fd def pre_render(self): @@ -2936,11 +2960,12 @@ class path_t_converter(CConverter): return str(int(bool(value))) # add self.py_name here when merging with posixmodule conversion - self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {}, {})'.format( + self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {}, {}, {})'.format( self.function.name, self.name, strify(self.nullable), strify(self.null_embeddable), + strify(self.make_wide), strify(self.allow_fd), ) @@ -3021,7 +3046,7 @@ class sysconf_confname_converter(path_confname_converter): converter="conv_sysconf_confname" [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=f1a792e1921bd863]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=b9dc54246b32902c]*/ /*[clinic input] @@ -5096,30 +5121,36 @@ os__path_splitroot_impl(PyObject *module, path_t *path) /*[clinic input] os._path_isdir - s as path: path_t(null_embeddable=True, allow_fd=True) + s: object Return true if the pathname refers to an existing directory. [clinic start generated code]*/ static PyObject * -os__path_isdir_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=0adeafd60704f710 input=ea7242408dd79e95]*/ +os__path_isdir_impl(PyObject *module, PyObject *s) +/*[clinic end generated code: output=9d87ab3c8b8a4e61 input=6e8f9d9f66f85cbc]*/ { HANDLE hfile; BOOL close_file = TRUE; FILE_BASIC_INFO info; + path_t _path = PATH_T_INITIALIZE("isdir", "s", 0, 0, 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (path->wide && wcslen(path->wide) != path->length) { - Py_RETURN_FALSE; + if (!path_converter(s, &_path)) { + path_cleanup(&_path); + if (PyErr_ExceptionMatches(PyExc_ValueError)) { + PyErr_Clear(); + Py_RETURN_FALSE; + } + return NULL; } Py_BEGIN_ALLOW_THREADS - if (path->wide) { - if (_Py_GetFileInformationByName(path->wide, FileStatBasicByNameInfo, + if (_path.wide) { + if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo, &statInfo, sizeof(statInfo))) { if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { slow_path = FALSE; @@ -5134,12 +5165,12 @@ os__path_isdir_impl(PyObject *module, path_t *path) } } if (slow_path) { - if (path->fd != -1) { - hfile = _Py_get_osfhandle_noraise(path->fd); + if (_path.fd != -1) { + hfile = _Py_get_osfhandle_noraise(_path.fd); close_file = FALSE; } else { - hfile = CreateFileW(path->wide, FILE_READ_ATTRIBUTES, 0, NULL, + hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); } if (hfile != INVALID_HANDLE_VALUE) { @@ -5162,7 +5193,7 @@ os__path_isdir_impl(PyObject *module, path_t *path) case ERROR_SHARING_VIOLATION: case ERROR_CANT_ACCESS_FILE: case ERROR_INVALID_PARAMETER: - if (STAT(path->wide, &st)) { + if (STAT(_path.wide, &st)) { result = 0; } else { @@ -5176,6 +5207,7 @@ os__path_isdir_impl(PyObject *module, path_t *path) } Py_END_ALLOW_THREADS + path_cleanup(&_path); if (result) { Py_RETURN_TRUE; } @@ -5186,30 +5218,36 @@ os__path_isdir_impl(PyObject *module, path_t *path) /*[clinic input] os._path_isfile - path: path_t(null_embeddable=True, allow_fd=True) + path: object Test whether a path is a regular file [clinic start generated code]*/ static PyObject * -os__path_isfile_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=4f72e7b1ada002da input=4ab9dca4fbc441b1]*/ +os__path_isfile_impl(PyObject *module, PyObject *path) +/*[clinic end generated code: output=2394ed7c4b5cfd85 input=b37b8017895208b2]*/ { HANDLE hfile; BOOL close_file = TRUE; FILE_BASIC_INFO info; + path_t _path = PATH_T_INITIALIZE("isfile", "path", 0, 0, 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (path->wide && wcslen(path->wide) != path->length) { - Py_RETURN_FALSE; + if (!path_converter(path, &_path)) { + path_cleanup(&_path); + if (PyErr_ExceptionMatches(PyExc_ValueError)) { + PyErr_Clear(); + Py_RETURN_FALSE; + } + return NULL; } Py_BEGIN_ALLOW_THREADS - if (path->wide) { - if (_Py_GetFileInformationByName(path->wide, FileStatBasicByNameInfo, + if (_path.wide) { + if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo, &statInfo, sizeof(statInfo))) { if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { slow_path = FALSE; @@ -5224,12 +5262,12 @@ os__path_isfile_impl(PyObject *module, path_t *path) } } if (slow_path) { - if (path->fd != -1) { - hfile = _Py_get_osfhandle_noraise(path->fd); + if (_path.fd != -1) { + hfile = _Py_get_osfhandle_noraise(_path.fd); close_file = FALSE; } else { - hfile = CreateFileW(path->wide, FILE_READ_ATTRIBUTES, 0, NULL, + hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); } if (hfile != INVALID_HANDLE_VALUE) { @@ -5252,7 +5290,7 @@ os__path_isfile_impl(PyObject *module, path_t *path) case ERROR_SHARING_VIOLATION: case ERROR_CANT_ACCESS_FILE: case ERROR_INVALID_PARAMETER: - if (STAT(path->wide, &st)) { + if (STAT(_path.wide, &st)) { result = 0; } else { @@ -5266,6 +5304,7 @@ os__path_isfile_impl(PyObject *module, path_t *path) } Py_END_ALLOW_THREADS + path_cleanup(&_path); if (result) { Py_RETURN_TRUE; } @@ -5276,29 +5315,35 @@ os__path_isfile_impl(PyObject *module, path_t *path) /*[clinic input] os._path_exists - path: path_t(null_embeddable=True, allow_fd=True) + path: object Test whether a path exists. Returns False for broken symbolic links [clinic start generated code]*/ static PyObject * -os__path_exists_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=69e6089df1fe463a input=bfd8cf0f7e09722f]*/ +os__path_exists_impl(PyObject *module, PyObject *path) +/*[clinic end generated code: output=f508c3b35e13a249 input=d0e5ab7388302942]*/ { HANDLE hfile; BOOL close_file = TRUE; + path_t _path = PATH_T_INITIALIZE("exists", "path", 0, 0, 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (path->wide && wcslen(path->wide) != path->length) { - Py_RETURN_FALSE; + if (!path_converter(path, &_path)) { + path_cleanup(&_path); + if (PyErr_ExceptionMatches(PyExc_ValueError)) { + PyErr_Clear(); + Py_RETURN_FALSE; + } + return NULL; } Py_BEGIN_ALLOW_THREADS - if (path->wide) { - if (_Py_GetFileInformationByName(path->wide, FileStatBasicByNameInfo, + if (_path.wide) { + if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo, &statInfo, sizeof(statInfo))) { if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { slow_path = FALSE; @@ -5310,12 +5355,12 @@ os__path_exists_impl(PyObject *module, path_t *path) } } if (slow_path) { - if (path->fd != -1) { - hfile = _Py_get_osfhandle_noraise(path->fd); + if (_path.fd != -1) { + hfile = _Py_get_osfhandle_noraise(_path.fd); close_file = FALSE; } else { - hfile = CreateFileW(path->wide, FILE_READ_ATTRIBUTES, 0, NULL, + hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); } if (hfile != INVALID_HANDLE_VALUE) { @@ -5331,7 +5376,7 @@ os__path_exists_impl(PyObject *module, path_t *path) case ERROR_SHARING_VIOLATION: case ERROR_CANT_ACCESS_FILE: case ERROR_INVALID_PARAMETER: - if (STAT(path->wide, &st)) { + if (STAT(_path.wide, &st)) { result = 0; } else { @@ -5345,6 +5390,7 @@ os__path_exists_impl(PyObject *module, path_t *path) } Py_END_ALLOW_THREADS + path_cleanup(&_path); if (result) { Py_RETURN_TRUE; } @@ -5355,30 +5401,36 @@ os__path_exists_impl(PyObject *module, path_t *path) /*[clinic input] os._path_islink - path: path_t(null_embeddable=True, allow_fd=True) + path: object Test whether a path is a symbolic link [clinic start generated code]*/ static PyObject * -os__path_islink_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=109ad77ec747b3b7 input=380264532e0862a3]*/ +os__path_islink_impl(PyObject *module, PyObject *path) +/*[clinic end generated code: output=6d8640b1a390c054 input=1a7c08fbe89b1ed6]*/ { HANDLE hfile; BOOL close_file = TRUE; FILE_ATTRIBUTE_TAG_INFO info; + path_t _path = PATH_T_INITIALIZE("islink", "path", 0, 0, 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (path->wide && wcslen(path->wide) != path->length) { - Py_RETURN_FALSE; + if (!path_converter(path, &_path)) { + path_cleanup(&_path); + if (PyErr_ExceptionMatches(PyExc_ValueError)) { + PyErr_Clear(); + Py_RETURN_FALSE; + } + return NULL; } Py_BEGIN_ALLOW_THREADS - if (path->wide) { - if (_Py_GetFileInformationByName(path->wide, FileStatBasicByNameInfo, + if (_path.wide) { + if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo, &statInfo, sizeof(statInfo))) { slow_path = FALSE; if (statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { @@ -5393,12 +5445,12 @@ os__path_islink_impl(PyObject *module, path_t *path) } } if (slow_path) { - if (path->fd != -1) { - hfile = _Py_get_osfhandle_noraise(path->fd); + if (_path.fd != -1) { + hfile = _Py_get_osfhandle_noraise(_path.fd); close_file = FALSE; } else { - hfile = CreateFileW(path->wide, FILE_READ_ATTRIBUTES, 0, NULL, + hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); @@ -5423,7 +5475,7 @@ os__path_islink_impl(PyObject *module, path_t *path) case ERROR_SHARING_VIOLATION: case ERROR_CANT_ACCESS_FILE: case ERROR_INVALID_PARAMETER: - if (LSTAT(path->wide, &st)) { + if (LSTAT(_path.wide, &st)) { result = 0; } else { @@ -5437,6 +5489,7 @@ os__path_islink_impl(PyObject *module, path_t *path) } Py_END_ALLOW_THREADS + path_cleanup(&_path); if (result) { Py_RETURN_TRUE; } @@ -5449,23 +5502,22 @@ os__path_islink_impl(PyObject *module, path_t *path) /*[clinic input] os._path_splitroot_ex - path: unicode + path: path_t(null_embeddable=True, make_wide=True) + +Split a pathname into drive, root and tail. +The tail contains anything after the root. [clinic start generated code]*/ static PyObject * -os__path_splitroot_ex_impl(PyObject *module, PyObject *path) -/*[clinic end generated code: output=de97403d3dfebc40 input=f1470e12d899f9ac]*/ +os__path_splitroot_ex_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=4b0072b6cdf4b611 input=fa388b51979a2f57]*/ { - Py_ssize_t len, drvsize, rootsize; + Py_ssize_t drvsize, rootsize; PyObject *drv = NULL, *root = NULL, *tail = NULL, *result = NULL; - wchar_t *buffer = PyUnicode_AsWideCharString(path, &len); - if (!buffer) { - goto exit; - } - - _Py_skiproot(buffer, len, &drvsize, &rootsize); + const wchar_t *buffer = path->wide; + _Py_skiproot(buffer, path->length, &drvsize, &rootsize); drv = PyUnicode_FromWideChar(buffer, drvsize); if (drv == NULL) { goto exit; @@ -5475,13 +5527,17 @@ os__path_splitroot_ex_impl(PyObject *module, PyObject *path) goto exit; } tail = PyUnicode_FromWideChar(&buffer[drvsize + rootsize], - len - drvsize - rootsize); + path->length - drvsize - rootsize); if (tail == NULL) { goto exit; } + if (PyBytes_Check(path->object)) { + Py_SETREF(drv, PyUnicode_EncodeFSDefault(drv)); + Py_SETREF(root, PyUnicode_EncodeFSDefault(root)); + Py_SETREF(tail, PyUnicode_EncodeFSDefault(tail)); + } result = Py_BuildValue("(OOO)", drv, root, tail); exit: - PyMem_Free(buffer); Py_XDECREF(drv); Py_XDECREF(root); Py_XDECREF(tail); @@ -5492,29 +5548,28 @@ os__path_splitroot_ex_impl(PyObject *module, PyObject *path) /*[clinic input] os._path_normpath - path: object + path: path_t(null_embeddable=True, make_wide=True) -Basic path normalization. +Normalize path, eliminating double slashes, etc. [clinic start generated code]*/ static PyObject * -os__path_normpath_impl(PyObject *module, PyObject *path) -/*[clinic end generated code: output=b94d696d828019da input=5e90c39e12549dc0]*/ +os__path_normpath_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=d353e7ed9410c044 input=4842c54b2fbdfc83]*/ { - if (!PyUnicode_Check(path)) { - PyErr_Format(PyExc_TypeError, "expected 'str', not '%.200s'", - Py_TYPE(path)->tp_name); - return NULL; + PyObject *result; + Py_ssize_t norm_len; + wchar_t *norm_path = _Py_normpath_and_size((wchar_t *)path->wide, + path->length, &norm_len); + if (!norm_len) { + result = PyUnicode_FromOrdinal('.'); } - Py_ssize_t len; - wchar_t *buffer = PyUnicode_AsWideCharString(path, &len); - if (!buffer) { - return NULL; + else { + result = PyUnicode_FromWideChar(norm_path, norm_len); + } + if (PyBytes_Check(path->object)) { + Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); } - Py_ssize_t norm_len; - wchar_t *norm_path = _Py_normpath_and_size(buffer, len, &norm_len); - PyObject *result = PyUnicode_FromWideChar(norm_path, norm_len); - PyMem_Free(buffer); return result; } From 28b4b6e8f00def8c44c164167d4c0eb7c532baa3 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sun, 28 Apr 2024 19:51:01 +0000 Subject: [PATCH 03/26] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2024-04-28-19-51-00.gh-issue-118263.Gaap3S.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-04-28-19-51-00.gh-issue-118263.Gaap3S.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-04-28-19-51-00.gh-issue-118263.Gaap3S.rst b/Misc/NEWS.d/next/Core and Builtins/2024-04-28-19-51-00.gh-issue-118263.Gaap3S.rst new file mode 100644 index 00000000000000..165a1ba69a811b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-04-28-19-51-00.gh-issue-118263.Gaap3S.rst @@ -0,0 +1 @@ +Speed up :func:`os.path.splitroot` & :func:`os.path.normpath` with a direct C call. From 19209c69bc67f363276ea3bb73980a688f902430 Mon Sep 17 00:00:00 2001 From: nineteendo Date: Sun, 28 Apr 2024 21:59:50 +0200 Subject: [PATCH 04/26] Fix typo & add type casts --- Modules/posixmodule.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 69db201b64b2d9..e3236a566ae116 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1307,7 +1307,7 @@ path_converter(PyObject *o, void *p) goto error_exit; } #endif - if (!path->null_embeddable && wcslen(wide) != length) { + if (!path->null_embeddable && wcslen(wide) != (size_t)length) { FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); goto error_exit; @@ -1361,7 +1361,7 @@ path_converter(PyObject *o, void *p) length = PyBytes_GET_SIZE(bytes); narrow = PyBytes_AS_STRING(bytes); - if (!path->null_embeddable && (size_t)length != strlen(narrow)) { + if (!path->null_embeddable && strlen(narrow) != (size_t)length) { FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); goto error_exit; } @@ -1385,7 +1385,7 @@ path_converter(PyObject *o, void *p) goto error_exit; } #endif - if (!path->null_embeddable && wcslen(wide) != length) { + if (!path->null_embeddable && wcslen(wide) != (size_t)length) { FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); goto error_exit; @@ -1394,7 +1394,7 @@ path_converter(PyObject *o, void *p) #ifdef MS_WINDOWS path->narrow = TRUE; #else - path->narrow = narrow + path->narrow = narrow; #endif Py_DECREF(bytes); wide = NULL; From 7ca6036a05f26bdb811ea7e2b83056eb1e19688c Mon Sep 17 00:00:00 2001 From: nineteendo Date: Sun, 28 Apr 2024 23:16:45 +0200 Subject: [PATCH 05/26] Add test for fast paths --- Lib/test/test_ntpath.py | 4 ++++ Lib/test/test_posixpath.py | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 7f91bf1c2b837a..9a3d8d6392302f 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -1108,6 +1108,10 @@ def test_fast_paths_in_use(self): # There are fast paths of these functions implemented in posixmodule.c. # Confirm that they are being used, and not the Python fallbacks in # genericpath.py. + self.assertTrue(os.path.splitroot is nt._path_splitroot_ex) + self.assertFalse(inspect.isfunction(os.path.splitroot)) + self.assertTrue(os.path.normpath is nt._path_normpath) + self.assertFalse(inspect.isfunction(os.path.normpath)) self.assertTrue(os.path.isdir is nt._path_isdir) self.assertFalse(inspect.isfunction(os.path.isdir)) self.assertTrue(os.path.isfile is nt._path_isfile) diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index 32a20efbb64e1d..137bbb7f945aac 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -1,3 +1,4 @@ +import inspect import os import posixpath import sys @@ -5,7 +6,7 @@ from posixpath import realpath, abspath, dirname, basename from test import test_genericpath from test.support import import_helper -from test.support import os_helper +from test.support import cpython_only, os_helper from test.support.os_helper import FakePath from unittest import mock @@ -283,6 +284,16 @@ def fake_lstat(path): def test_isjunction(self): self.assertFalse(posixpath.isjunction(ABSTFN)) + @unittest.skipIf(sys.platform == 'win32', "Fast paths are not for win32") + @cpython_only + def test_fast_paths_in_use(self): + # There are fast paths of these functions implemented in posixmodule.c. + # Confirm that they are being used, and not the Python fallbacks + self.assertTrue(os.path.splitroot is posix._path_splitroot_ex) + self.assertFalse(inspect.isfunction(os.path.splitroot)) + self.assertTrue(os.path.normpath is posix._path_normpath) + self.assertFalse(inspect.isfunction(os.path.normpath)) + def test_expanduser(self): self.assertEqual(posixpath.expanduser("foo"), "foo") self.assertEqual(posixpath.expanduser(b"foo"), b"foo") From 55c188324b59954b1945a286392aba2a943b39dd Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Mon, 29 Apr 2024 09:36:39 +0200 Subject: [PATCH 06/26] Build tuple faster --- Modules/posixmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index e3236a566ae116..68aeaa206b0e5a 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5536,7 +5536,7 @@ os__path_splitroot_ex_impl(PyObject *module, path_t *path) Py_SETREF(root, PyUnicode_EncodeFSDefault(root)); Py_SETREF(tail, PyUnicode_EncodeFSDefault(tail)); } - result = Py_BuildValue("(OOO)", drv, root, tail); + result = PyTuple_Pack(3, drv, root, tail); exit: Py_XDECREF(drv); Py_XDECREF(root); From 1c93617f36e264537e5d3c6298571e8df67d3b10 Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Fri, 3 May 2024 21:39:34 +0200 Subject: [PATCH 07/26] Support `make_wide=False` on Windows --- Modules/clinic/posixmodule.c.h | 116 ++++++++++++++++----------------- Modules/posixmodule.c | 83 ++++++++++------------- 2 files changed, 91 insertions(+), 108 deletions(-) diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 5015e65b6f2e2a..9bbb8da2982932 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -72,7 +72,7 @@ os_stat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("stat", "path", 0, 0, 0, 1); + path_t path = PATH_T_INITIALIZE_P("stat", "path", 0, 0, 1); int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; @@ -154,7 +154,7 @@ os_lstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("lstat", "path", 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -250,7 +250,7 @@ os_access(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("access", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("access", "path", 0, 0, 0); int mode; int dir_fd = DEFAULT_DIR_FD; int effective_ids = 0; @@ -409,7 +409,7 @@ os_chdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("chdir", "path", 0, 0, 0, PATH_HAVE_FCHDIR); + path_t path = PATH_T_INITIALIZE_P("chdir", "path", 0, 0, PATH_HAVE_FCHDIR); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -560,7 +560,7 @@ os_chmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("chmod", "path", 0, 0, 0, PATH_HAVE_FCHMOD); + path_t path = PATH_T_INITIALIZE_P("chmod", "path", 0, 0, PATH_HAVE_FCHMOD); int mode; int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = CHMOD_DEFAULT_FOLLOW_SYMLINKS; @@ -725,7 +725,7 @@ os_lchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("lchmod", "path", 0, 0, 0); int mode; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -802,7 +802,7 @@ os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("chflags", "path", 0, 0, 0); unsigned long flags; int follow_symlinks = 1; @@ -884,7 +884,7 @@ os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject }; #undef KWTUPLE PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("lchflags", "path", 0, 0, 0); unsigned long flags; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -954,7 +954,7 @@ os_chroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("chroot", "path", 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -1190,7 +1190,7 @@ os_chown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE("chown", "path", 0, 0, 0, PATH_HAVE_FCHOWN); + path_t path = PATH_T_INITIALIZE_P("chown", "path", 0, 0, PATH_HAVE_FCHOWN); uid_t uid; gid_t gid; int dir_fd = DEFAULT_DIR_FD; @@ -1355,7 +1355,7 @@ os_lchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[3]; - path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("lchown", "path", 0, 0, 0); uid_t uid; gid_t gid; @@ -1476,8 +1476,8 @@ os_link(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE("link", "src", 0, 0, 0, 0); - path_t dst = PATH_T_INITIALIZE("link", "dst", 0, 0, 0, 0); + path_t src = PATH_T_INITIALIZE_P("link", "src", 0, 0, 0); + path_t dst = PATH_T_INITIALIZE_P("link", "dst", 0, 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; @@ -1583,7 +1583,7 @@ os_listdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - path_t path = PATH_T_INITIALIZE("listdir", "path", 1, 0, 0, PATH_HAVE_FDOPENDIR); + path_t path = PATH_T_INITIALIZE_P("listdir", "path", 1, 0, PATH_HAVE_FDOPENDIR); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { @@ -1699,7 +1699,7 @@ os_listmounts(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t volume = PATH_T_INITIALIZE("listmounts", "volume", 0, 0, 0, 0); + path_t volume = PATH_T_INITIALIZE_P("listmounts", "volume", 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -1763,7 +1763,7 @@ os__path_isdevdrive(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_path_isdevdrive", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("_path_isdevdrive", "path", 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -1800,7 +1800,7 @@ static PyObject * os__getfullpathname(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE("_getfullpathname", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("_getfullpathname", "path", 0, 0, 0); if (!path_converter(arg, &path)) { goto exit; @@ -1834,7 +1834,7 @@ static PyObject * os__getfinalpathname(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE("_getfinalpathname", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("_getfinalpathname", "path", 0, 0, 0); if (!path_converter(arg, &path)) { goto exit; @@ -1868,7 +1868,7 @@ static PyObject * os__findfirstfile(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE("_findfirstfile", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("_findfirstfile", "path", 0, 0, 0); if (!path_converter(arg, &path)) { goto exit; @@ -1928,7 +1928,7 @@ os__getvolumepathname(PyObject *module, PyObject *const *args, Py_ssize_t nargs, }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_getvolumepathname", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("_getvolumepathname", "path", 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -1992,7 +1992,7 @@ os__path_splitroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_path_splitroot", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("_path_splitroot", "path", 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -2421,7 +2421,7 @@ os_mkdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("mkdir", "path", 0, 0, 0); int mode = 511; int dir_fd = DEFAULT_DIR_FD; @@ -2682,8 +2682,8 @@ os_rename(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0, 0, 0); - path_t dst = PATH_T_INITIALIZE("rename", "dst", 0, 0, 0, 0); + path_t src = PATH_T_INITIALIZE_P("rename", "src", 0, 0, 0); + path_t dst = PATH_T_INITIALIZE_P("rename", "dst", 0, 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; @@ -2773,8 +2773,8 @@ os_replace(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE("replace", "src", 0, 0, 0, 0); - path_t dst = PATH_T_INITIALIZE("replace", "dst", 0, 0, 0, 0); + path_t src = PATH_T_INITIALIZE_P("replace", "src", 0, 0, 0); + path_t dst = PATH_T_INITIALIZE_P("replace", "dst", 0, 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; @@ -2862,7 +2862,7 @@ os_rmdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("rmdir", "path", 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -3111,7 +3111,7 @@ os_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("unlink", "path", 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -3185,7 +3185,7 @@ os_remove(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("remove", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("remove", "path", 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -3303,7 +3303,7 @@ os_utime(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("utime", "path", 0, 0, 0, PATH_UTIME_HAVE_FD); + path_t path = PATH_T_INITIALIZE_P("utime", "path", 0, 0, PATH_UTIME_HAVE_FD); PyObject *times = Py_None; PyObject *ns = NULL; int dir_fd = DEFAULT_DIR_FD; @@ -3438,7 +3438,7 @@ static PyObject * os_execv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE("execv", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("execv", "path", 0, 0, 0); PyObject *argv; if (!_PyArg_CheckPositional("execv", nargs, 2, 2)) { @@ -3510,7 +3510,7 @@ os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[3]; - path_t path = PATH_T_INITIALIZE("execve", "path", 0, 0, 0, PATH_HAVE_FEXECVE); + path_t path = PATH_T_INITIALIZE_P("execve", "path", 0, 0, PATH_HAVE_FEXECVE); PyObject *argv; PyObject *env; @@ -3606,7 +3606,7 @@ os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #undef KWTUPLE PyObject *argsbuf[10]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE("posix_spawn", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("posix_spawn", "path", 0, 0, 0); PyObject *argv; PyObject *env; PyObject *file_actions = NULL; @@ -3756,7 +3756,7 @@ os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj #undef KWTUPLE PyObject *argsbuf[10]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE("posix_spawnp", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("posix_spawnp", "path", 0, 0, 0); PyObject *argv; PyObject *env; PyObject *file_actions = NULL; @@ -3860,7 +3860,7 @@ os_spawnv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; int mode; - path_t path = PATH_T_INITIALIZE("spawnv", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("spawnv", "path", 0, 0, 0); PyObject *argv; if (!_PyArg_CheckPositional("spawnv", nargs, 3, 3)) { @@ -3914,7 +3914,7 @@ os_spawnve(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; int mode; - path_t path = PATH_T_INITIALIZE("spawnve", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("spawnve", "path", 0, 0, 0); PyObject *argv; PyObject *env; @@ -6090,7 +6090,7 @@ os_readlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("readlink", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("readlink", "path", 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -6174,8 +6174,8 @@ os_symlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE("symlink", "src", 0, 0, 0, 0); - path_t dst = PATH_T_INITIALIZE("symlink", "dst", 0, 0, 0, 0); + path_t src = PATH_T_INITIALIZE_P("symlink", "src", 0, 0, 0); + path_t dst = PATH_T_INITIALIZE_P("symlink", "dst", 0, 0, 0); int target_is_directory = 0; int dir_fd = DEFAULT_DIR_FD; @@ -6817,7 +6817,7 @@ os_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("open", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("open", "path", 0, 0, 0); int flags; int mode = 511; int dir_fd = DEFAULT_DIR_FD; @@ -8405,7 +8405,7 @@ os_mkfifo(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("mkfifo", "path", 0, 0, 0); int mode = 438; int dir_fd = DEFAULT_DIR_FD; @@ -8505,7 +8505,7 @@ os_mknod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("mknod", "path", 0, 0, 0); int mode = 384; dev_t device = 0; int dir_fd = DEFAULT_DIR_FD; @@ -8759,7 +8759,7 @@ os_truncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject }; #undef KWTUPLE PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE("truncate", "path", 0, 0, 0, PATH_HAVE_FTRUNCATE); + path_t path = PATH_T_INITIALIZE_P("truncate", "path", 0, 0, PATH_HAVE_FTRUNCATE); Py_off_t length; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -9658,7 +9658,7 @@ os_statvfs(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, 0, 0, PATH_HAVE_FSTATVFS); + path_t path = PATH_T_INITIALIZE_P("statvfs", "path", 0, 0, PATH_HAVE_FSTATVFS); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -9722,7 +9722,7 @@ os__getdiskusage(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_getdiskusage", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("_getdiskusage", "path", 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -9836,7 +9836,7 @@ os_pathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject }; #undef KWTUPLE PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, 0, 0, PATH_HAVE_FPATHCONF); + path_t path = PATH_T_INITIALIZE_P("pathconf", "path", 0, 0, PATH_HAVE_FPATHCONF); int name; long _return_value; @@ -10026,10 +10026,10 @@ os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t filepath = PATH_T_INITIALIZE("startfile", "filepath", 0, 0, 0, 0); + path_t filepath = PATH_T_INITIALIZE_P("startfile", "filepath", 0, 0, 0); const wchar_t *operation = NULL; const wchar_t *arguments = NULL; - path_t cwd = PATH_T_INITIALIZE("startfile", "cwd", 1, 0, 0, 0); + path_t cwd = PATH_T_INITIALIZE_P("startfile", "cwd", 1, 0, 0); int show_cmd = 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 5, 0, argsbuf); @@ -10364,8 +10364,8 @@ os_getxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 0, 0, 1); - path_t attribute = PATH_T_INITIALIZE("getxattr", "attribute", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("getxattr", "path", 0, 0, 1); + path_t attribute = PATH_T_INITIALIZE_P("getxattr", "attribute", 0, 0, 0); int follow_symlinks = 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -10451,8 +10451,8 @@ os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE("setxattr", "path", 0, 0, 0, 1); - path_t attribute = PATH_T_INITIALIZE("setxattr", "attribute", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("setxattr", "path", 0, 0, 1); + path_t attribute = PATH_T_INITIALIZE_P("setxattr", "attribute", 0, 0, 0); Py_buffer value = {NULL, NULL}; int flags = 0; int follow_symlinks = 1; @@ -10559,8 +10559,8 @@ os_removexattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 0, 0, 1); - path_t attribute = PATH_T_INITIALIZE("removexattr", "attribute", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("removexattr", "path", 0, 0, 1); + path_t attribute = PATH_T_INITIALIZE_P("removexattr", "attribute", 0, 0, 0); int follow_symlinks = 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -10645,7 +10645,7 @@ os_listxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 0, 0, 1); + path_t path = PATH_T_INITIALIZE_P("listxattr", "path", 1, 0, 1); int follow_symlinks = 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); @@ -11622,7 +11622,7 @@ os_scandir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - path_t path = PATH_T_INITIALIZE("scandir", "path", 1, 0, 0, PATH_HAVE_FDOPENDIR); + path_t path = PATH_T_INITIALIZE_P("scandir", "path", 1, 0, PATH_HAVE_FDOPENDIR); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { @@ -11834,7 +11834,7 @@ os__add_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs, }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_add_dll_directory", "path", 0, 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("_add_dll_directory", "path", 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -12669,4 +12669,4 @@ os__supports_virtual_terminal(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF #define OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF #endif /* !defined(OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF) */ -/*[clinic end generated code: output=bfd2d2216e6079a8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=fab60e954c4367e1 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 68aeaa206b0e5a..1de1125917c769 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1130,9 +1130,7 @@ get_posix_state(PyObject *module) * and was not encoded. * path.narrow * Points to the path if it was expressed as bytes, - * or it was Unicode and was encoded to bytes. (On Windows, - * is a non-zero integer if the path was expressed as bytes. - * The type is deliberately incompatible to prevent misuse.) + * or it was Unicode and was encoded to bytes. * path.fd * Contains a file descriptor if path.accept_fd was true * and the caller provided a signed integer instead of any @@ -1183,27 +1181,27 @@ typedef struct { int allow_fd; // Output fields const wchar_t *wide; -#ifdef MS_WINDOWS - BOOL narrow; -#else const char *narrow; -#endif int fd; Py_ssize_t length; PyObject *object; PyObject *cleanup; } path_t; -#ifdef MS_WINDOWS -#define PATH_T_INITIALIZE(function_name, argument_name, nullable, \ - null_embeddable, make_wide, allow_fd) \ - {function_name, argument_name, nullable, null_embeddable, make_wide, \ - allow_fd, NULL, FALSE, -1, 0, NULL, NULL} -#else #define PATH_T_INITIALIZE(function_name, argument_name, nullable, \ null_embeddable, make_wide, allow_fd) \ {function_name, argument_name, nullable, null_embeddable, make_wide, \ allow_fd, NULL, NULL, -1, 0, NULL, NULL} +#ifdef MS_WINDOWS +#define PATH_T_INITIALIZE_P(function_name, argument_name, nullable, \ + null_embeddable, allow_fd) \ + PATH_T_INITIALIZE(function_name, argument_name, nullable, \ + null_embeddable, 1, allow_fd) +#else +#define PATH_T_INITIALIZE_P(function_name, argument_name, nullable, \ + null_embeddable, allow_fd) \ + PATH_T_INITIALIZE(function_name, argument_name, nullable, \ + null_embeddable, 0, allow_fd) #endif static void @@ -1246,11 +1244,7 @@ path_converter(PyObject *o, void *p) if ((o == Py_None) && path->nullable) { path->wide = NULL; -#ifdef MS_WINDOWS - path->narrow = FALSE; -#else path->narrow = NULL; -#endif path->fd = -1; goto success_exit; } @@ -1294,9 +1288,7 @@ path_converter(PyObject *o, void *p) } if (is_unicode) { -#ifndef MS_WINDOWS if (path->make_wide) { -#endif wide = PyUnicode_AsWideCharString(o, &length); if (!wide) { goto error_exit; @@ -1314,20 +1306,14 @@ path_converter(PyObject *o, void *p) } path->wide = wide; -#ifdef MS_WINDOWS - path->narrow = FALSE; -#else path->narrow = NULL; -#endif path->fd = -1; wide = NULL; goto success_exit; -#ifndef MS_WINDOWS } if (!_PyUnicode_FSConverter(o, &bytes, path->null_embeddable)) { goto error_exit; } -#endif } else if (is_bytes) { bytes = Py_NewRef(o); @@ -1337,11 +1323,7 @@ path_converter(PyObject *o, void *p) goto error_exit; } path->wide = NULL; -#ifdef MS_WINDOWS - path->narrow = FALSE; -#else path->narrow = NULL; -#endif goto success_exit; } else { @@ -1366,9 +1348,7 @@ path_converter(PyObject *o, void *p) goto error_exit; } -#ifndef MS_WINDOWS if (path->make_wide) { -#endif wo = PyUnicode_DecodeFSDefaultAndSize(narrow, length); if (!wo) { goto error_exit; @@ -1391,14 +1371,9 @@ path_converter(PyObject *o, void *p) goto error_exit; } path->wide = wide; -#ifdef MS_WINDOWS - path->narrow = TRUE; -#else - path->narrow = narrow; -#endif + path->narrow = narrow; // TODO: replace by NULL Py_DECREF(bytes); wide = NULL; -#ifndef MS_WINDOWS } else { path->wide = NULL; @@ -1412,7 +1387,6 @@ path_converter(PyObject *o, void *p) path->cleanup = bytes; } } -#endif path->fd = -1; success_exit: @@ -2938,7 +2912,7 @@ class path_t_converter(CConverter): converter = 'path_converter' - def converter_init(self, *, allow_fd=False, make_wide=False, + def converter_init(self, *, allow_fd=False, make_wide=None, nullable=False, null_embeddable=False): # right now path_t doesn't support default values. # to support a default value, you'll need to override initialize(). @@ -2960,13 +2934,22 @@ class path_t_converter(CConverter): return str(int(bool(value))) # add self.py_name here when merging with posixmodule conversion - self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {}, {}, {})'.format( - self.function.name, - self.name, - strify(self.nullable), - strify(self.null_embeddable), - strify(self.make_wide), - strify(self.allow_fd), + if self.make_wide is None: + self.c_default = 'PATH_T_INITIALIZE_P("{}", "{}", {}, {}, {})'.format( + self.function.name, + self.name, + strify(self.nullable), + strify(self.null_embeddable), + strify(self.allow_fd), + ) + else: + self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {}, {}, {})'.format( + self.function.name, + self.name, + strify(self.nullable), + strify(self.null_embeddable), + strify(self.make_wide), + strify(self.allow_fd), ) def cleanup(self): @@ -5134,7 +5117,7 @@ os__path_isdir_impl(PyObject *module, PyObject *s) HANDLE hfile; BOOL close_file = TRUE; FILE_BASIC_INFO info; - path_t _path = PATH_T_INITIALIZE("isdir", "s", 0, 0, 0, 1); + path_t _path = PATH_T_INITIALIZE_P("isdir", "s", 0, 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; @@ -5231,7 +5214,7 @@ os__path_isfile_impl(PyObject *module, PyObject *path) HANDLE hfile; BOOL close_file = TRUE; FILE_BASIC_INFO info; - path_t _path = PATH_T_INITIALIZE("isfile", "path", 0, 0, 0, 1); + path_t _path = PATH_T_INITIALIZE_P("isfile", "path", 0, 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; @@ -5327,7 +5310,7 @@ os__path_exists_impl(PyObject *module, PyObject *path) { HANDLE hfile; BOOL close_file = TRUE; - path_t _path = PATH_T_INITIALIZE("exists", "path", 0, 0, 0, 1); + path_t _path = PATH_T_INITIALIZE_P("exists", "path", 0, 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; @@ -5414,7 +5397,7 @@ os__path_islink_impl(PyObject *module, PyObject *path) HANDLE hfile; BOOL close_file = TRUE; FILE_ATTRIBUTE_TAG_INFO info; - path_t _path = PATH_T_INITIALIZE("islink", "path", 0, 0, 0, 1); + path_t _path = PATH_T_INITIALIZE_P("islink", "path", 0, 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; From dc36f2e7fe4451f34a13b6be467755c7990ddcef Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Fri, 3 May 2024 21:44:22 +0200 Subject: [PATCH 08/26] Update generated code --- Modules/posixmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 1de1125917c769..d34e14681ee96e 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -3029,7 +3029,7 @@ class sysconf_confname_converter(path_confname_converter): converter="conv_sysconf_confname" [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=b9dc54246b32902c]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=fe32fef4a3a19fe5]*/ /*[clinic input] From 0a9d497e672a7be1da91bedd0839c5a7ad220bca Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sat, 4 May 2024 07:29:53 +0200 Subject: [PATCH 09/26] Add `suppress` --- Modules/clinic/posixmodule.c.h | 172 ++++++++++++++++++--------------- Modules/posixmodule.c | 149 ++++++++++++++-------------- 2 files changed, 174 insertions(+), 147 deletions(-) diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 9bbb8da2982932..de6c9e2fbd07bb 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -72,7 +72,7 @@ os_stat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE_P("stat", "path", 0, 0, 1); + path_t path = PATH_T_INITIALIZE_P("stat", "path", 0, 0, 0, 1); int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; @@ -154,7 +154,7 @@ os_lstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE_P("lstat", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("lstat", "path", 0, 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -250,7 +250,7 @@ os_access(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE_P("access", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("access", "path", 0, 0, 0, 0); int mode; int dir_fd = DEFAULT_DIR_FD; int effective_ids = 0; @@ -409,7 +409,7 @@ os_chdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE_P("chdir", "path", 0, 0, PATH_HAVE_FCHDIR); + path_t path = PATH_T_INITIALIZE_P("chdir", "path", 0, 0, 0, PATH_HAVE_FCHDIR); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -560,7 +560,7 @@ os_chmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE_P("chmod", "path", 0, 0, PATH_HAVE_FCHMOD); + path_t path = PATH_T_INITIALIZE_P("chmod", "path", 0, 0, 0, PATH_HAVE_FCHMOD); int mode; int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = CHMOD_DEFAULT_FOLLOW_SYMLINKS; @@ -725,7 +725,7 @@ os_lchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE_P("lchmod", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("lchmod", "path", 0, 0, 0, 0); int mode; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -802,7 +802,7 @@ os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE_P("chflags", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("chflags", "path", 0, 0, 0, 0); unsigned long flags; int follow_symlinks = 1; @@ -884,7 +884,7 @@ os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject }; #undef KWTUPLE PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE_P("lchflags", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("lchflags", "path", 0, 0, 0, 0); unsigned long flags; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -954,7 +954,7 @@ os_chroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE_P("chroot", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("chroot", "path", 0, 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -1190,7 +1190,7 @@ os_chown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE_P("chown", "path", 0, 0, PATH_HAVE_FCHOWN); + path_t path = PATH_T_INITIALIZE_P("chown", "path", 0, 0, 0, PATH_HAVE_FCHOWN); uid_t uid; gid_t gid; int dir_fd = DEFAULT_DIR_FD; @@ -1355,7 +1355,7 @@ os_lchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[3]; - path_t path = PATH_T_INITIALIZE_P("lchown", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("lchown", "path", 0, 0, 0, 0); uid_t uid; gid_t gid; @@ -1476,8 +1476,8 @@ os_link(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE_P("link", "src", 0, 0, 0); - path_t dst = PATH_T_INITIALIZE_P("link", "dst", 0, 0, 0); + path_t src = PATH_T_INITIALIZE_P("link", "src", 0, 0, 0, 0); + path_t dst = PATH_T_INITIALIZE_P("link", "dst", 0, 0, 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; @@ -1583,7 +1583,7 @@ os_listdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - path_t path = PATH_T_INITIALIZE_P("listdir", "path", 1, 0, PATH_HAVE_FDOPENDIR); + path_t path = PATH_T_INITIALIZE_P("listdir", "path", 1, 0, 0, PATH_HAVE_FDOPENDIR); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { @@ -1699,7 +1699,7 @@ os_listmounts(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t volume = PATH_T_INITIALIZE_P("listmounts", "volume", 0, 0, 0); + path_t volume = PATH_T_INITIALIZE_P("listmounts", "volume", 0, 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -1763,7 +1763,7 @@ os__path_isdevdrive(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE_P("_path_isdevdrive", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("_path_isdevdrive", "path", 0, 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -1800,7 +1800,7 @@ static PyObject * os__getfullpathname(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE_P("_getfullpathname", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("_getfullpathname", "path", 0, 0, 0, 0); if (!path_converter(arg, &path)) { goto exit; @@ -1834,7 +1834,7 @@ static PyObject * os__getfinalpathname(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE_P("_getfinalpathname", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("_getfinalpathname", "path", 0, 0, 0, 0); if (!path_converter(arg, &path)) { goto exit; @@ -1868,7 +1868,7 @@ static PyObject * os__findfirstfile(PyObject *module, PyObject *arg) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE_P("_findfirstfile", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("_findfirstfile", "path", 0, 0, 0, 0); if (!path_converter(arg, &path)) { goto exit; @@ -1928,7 +1928,7 @@ os__getvolumepathname(PyObject *module, PyObject *const *args, Py_ssize_t nargs, }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE_P("_getvolumepathname", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("_getvolumepathname", "path", 0, 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -1992,7 +1992,7 @@ os__path_splitroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE_P("_path_splitroot", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("_path_splitroot", "path", 0, 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -2024,7 +2024,7 @@ PyDoc_STRVAR(os__path_isdir__doc__, {"_path_isdir", _PyCFunction_CAST(os__path_isdir), METH_FASTCALL|METH_KEYWORDS, os__path_isdir__doc__}, static PyObject * -os__path_isdir_impl(PyObject *module, PyObject *s); +os__path_isdir_impl(PyObject *module, path_t *path); static PyObject * os__path_isdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -2056,16 +2056,21 @@ os__path_isdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *s; + path_t path = PATH_T_INITIALIZE_P("_path_isdir", "path", 0, 0, 1, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - s = args[0]; - return_value = os__path_isdir_impl(module, s); + if (!path_converter(args[0], &path)) { + goto exit; + } + return_value = os__path_isdir_impl(module, &path); exit: + /* Cleanup for path */ + path_cleanup(&path); + return return_value; } @@ -2083,7 +2088,7 @@ PyDoc_STRVAR(os__path_isfile__doc__, {"_path_isfile", _PyCFunction_CAST(os__path_isfile), METH_FASTCALL|METH_KEYWORDS, os__path_isfile__doc__}, static PyObject * -os__path_isfile_impl(PyObject *module, PyObject *path); +os__path_isfile_impl(PyObject *module, path_t *path); static PyObject * os__path_isfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -2115,16 +2120,21 @@ os__path_isfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *path; + path_t path = PATH_T_INITIALIZE_P("_path_isfile", "path", 0, 0, 1, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - path = args[0]; - return_value = os__path_isfile_impl(module, path); + if (!path_converter(args[0], &path)) { + goto exit; + } + return_value = os__path_isfile_impl(module, &path); exit: + /* Cleanup for path */ + path_cleanup(&path); + return return_value; } @@ -2142,7 +2152,7 @@ PyDoc_STRVAR(os__path_exists__doc__, {"_path_exists", _PyCFunction_CAST(os__path_exists), METH_FASTCALL|METH_KEYWORDS, os__path_exists__doc__}, static PyObject * -os__path_exists_impl(PyObject *module, PyObject *path); +os__path_exists_impl(PyObject *module, path_t *path); static PyObject * os__path_exists(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -2174,16 +2184,21 @@ os__path_exists(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *path; + path_t path = PATH_T_INITIALIZE_P("_path_exists", "path", 0, 0, 1, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - path = args[0]; - return_value = os__path_exists_impl(module, path); + if (!path_converter(args[0], &path)) { + goto exit; + } + return_value = os__path_exists_impl(module, &path); exit: + /* Cleanup for path */ + path_cleanup(&path); + return return_value; } @@ -2201,7 +2216,7 @@ PyDoc_STRVAR(os__path_islink__doc__, {"_path_islink", _PyCFunction_CAST(os__path_islink), METH_FASTCALL|METH_KEYWORDS, os__path_islink__doc__}, static PyObject * -os__path_islink_impl(PyObject *module, PyObject *path); +os__path_islink_impl(PyObject *module, path_t *path); static PyObject * os__path_islink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -2233,16 +2248,21 @@ os__path_islink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj }; #undef KWTUPLE PyObject *argsbuf[1]; - PyObject *path; + path_t path = PATH_T_INITIALIZE_P("_path_islink", "path", 0, 0, 1, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { goto exit; } - path = args[0]; - return_value = os__path_islink_impl(module, path); + if (!path_converter(args[0], &path)) { + goto exit; + } + return_value = os__path_islink_impl(module, &path); exit: + /* Cleanup for path */ + path_cleanup(&path); + return return_value; } @@ -2292,7 +2312,7 @@ os__path_splitroot_ex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_path_splitroot_ex", "path", 0, 1, 1, 0); + path_t path = PATH_T_INITIALIZE("_path_splitroot_ex", "path", 0, 1, 1, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -2352,7 +2372,7 @@ os__path_normpath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE("_path_normpath", "path", 0, 1, 1, 0); + path_t path = PATH_T_INITIALIZE("_path_normpath", "path", 0, 1, 1, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -2421,7 +2441,7 @@ os_mkdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE_P("mkdir", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("mkdir", "path", 0, 0, 0, 0); int mode = 511; int dir_fd = DEFAULT_DIR_FD; @@ -2682,8 +2702,8 @@ os_rename(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE_P("rename", "src", 0, 0, 0); - path_t dst = PATH_T_INITIALIZE_P("rename", "dst", 0, 0, 0); + path_t src = PATH_T_INITIALIZE_P("rename", "src", 0, 0, 0, 0); + path_t dst = PATH_T_INITIALIZE_P("rename", "dst", 0, 0, 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; @@ -2773,8 +2793,8 @@ os_replace(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE_P("replace", "src", 0, 0, 0); - path_t dst = PATH_T_INITIALIZE_P("replace", "dst", 0, 0, 0); + path_t src = PATH_T_INITIALIZE_P("replace", "src", 0, 0, 0, 0); + path_t dst = PATH_T_INITIALIZE_P("replace", "dst", 0, 0, 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; @@ -2862,7 +2882,7 @@ os_rmdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE_P("rmdir", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("rmdir", "path", 0, 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -3111,7 +3131,7 @@ os_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE_P("unlink", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("unlink", "path", 0, 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -3185,7 +3205,7 @@ os_remove(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE_P("remove", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("remove", "path", 0, 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -3303,7 +3323,7 @@ os_utime(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE_P("utime", "path", 0, 0, PATH_UTIME_HAVE_FD); + path_t path = PATH_T_INITIALIZE_P("utime", "path", 0, 0, 0, PATH_UTIME_HAVE_FD); PyObject *times = Py_None; PyObject *ns = NULL; int dir_fd = DEFAULT_DIR_FD; @@ -3438,7 +3458,7 @@ static PyObject * os_execv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - path_t path = PATH_T_INITIALIZE_P("execv", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("execv", "path", 0, 0, 0, 0); PyObject *argv; if (!_PyArg_CheckPositional("execv", nargs, 2, 2)) { @@ -3510,7 +3530,7 @@ os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k }; #undef KWTUPLE PyObject *argsbuf[3]; - path_t path = PATH_T_INITIALIZE_P("execve", "path", 0, 0, PATH_HAVE_FEXECVE); + path_t path = PATH_T_INITIALIZE_P("execve", "path", 0, 0, 0, PATH_HAVE_FEXECVE); PyObject *argv; PyObject *env; @@ -3606,7 +3626,7 @@ os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #undef KWTUPLE PyObject *argsbuf[10]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE_P("posix_spawn", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("posix_spawn", "path", 0, 0, 0, 0); PyObject *argv; PyObject *env; PyObject *file_actions = NULL; @@ -3756,7 +3776,7 @@ os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj #undef KWTUPLE PyObject *argsbuf[10]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE_P("posix_spawnp", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("posix_spawnp", "path", 0, 0, 0, 0); PyObject *argv; PyObject *env; PyObject *file_actions = NULL; @@ -3860,7 +3880,7 @@ os_spawnv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; int mode; - path_t path = PATH_T_INITIALIZE_P("spawnv", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("spawnv", "path", 0, 0, 0, 0); PyObject *argv; if (!_PyArg_CheckPositional("spawnv", nargs, 3, 3)) { @@ -3914,7 +3934,7 @@ os_spawnve(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; int mode; - path_t path = PATH_T_INITIALIZE_P("spawnve", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("spawnve", "path", 0, 0, 0, 0); PyObject *argv; PyObject *env; @@ -6090,7 +6110,7 @@ os_readlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE_P("readlink", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("readlink", "path", 0, 0, 0, 0); int dir_fd = DEFAULT_DIR_FD; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); @@ -6174,8 +6194,8 @@ os_symlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t src = PATH_T_INITIALIZE_P("symlink", "src", 0, 0, 0); - path_t dst = PATH_T_INITIALIZE_P("symlink", "dst", 0, 0, 0); + path_t src = PATH_T_INITIALIZE_P("symlink", "src", 0, 0, 0, 0); + path_t dst = PATH_T_INITIALIZE_P("symlink", "dst", 0, 0, 0, 0); int target_is_directory = 0; int dir_fd = DEFAULT_DIR_FD; @@ -6817,7 +6837,7 @@ os_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE_P("open", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("open", "path", 0, 0, 0, 0); int flags; int mode = 511; int dir_fd = DEFAULT_DIR_FD; @@ -8405,7 +8425,7 @@ os_mkfifo(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE_P("mkfifo", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("mkfifo", "path", 0, 0, 0, 0); int mode = 438; int dir_fd = DEFAULT_DIR_FD; @@ -8505,7 +8525,7 @@ os_mknod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t path = PATH_T_INITIALIZE_P("mknod", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("mknod", "path", 0, 0, 0, 0); int mode = 384; dev_t device = 0; int dir_fd = DEFAULT_DIR_FD; @@ -8759,7 +8779,7 @@ os_truncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject }; #undef KWTUPLE PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE_P("truncate", "path", 0, 0, PATH_HAVE_FTRUNCATE); + path_t path = PATH_T_INITIALIZE_P("truncate", "path", 0, 0, 0, PATH_HAVE_FTRUNCATE); Py_off_t length; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -9658,7 +9678,7 @@ os_statvfs(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE_P("statvfs", "path", 0, 0, PATH_HAVE_FSTATVFS); + path_t path = PATH_T_INITIALIZE_P("statvfs", "path", 0, 0, 0, PATH_HAVE_FSTATVFS); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -9722,7 +9742,7 @@ os__getdiskusage(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE_P("_getdiskusage", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("_getdiskusage", "path", 0, 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -9836,7 +9856,7 @@ os_pathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject }; #undef KWTUPLE PyObject *argsbuf[2]; - path_t path = PATH_T_INITIALIZE_P("pathconf", "path", 0, 0, PATH_HAVE_FPATHCONF); + path_t path = PATH_T_INITIALIZE_P("pathconf", "path", 0, 0, 0, PATH_HAVE_FPATHCONF); int name; long _return_value; @@ -10026,10 +10046,10 @@ os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; - path_t filepath = PATH_T_INITIALIZE_P("startfile", "filepath", 0, 0, 0); + path_t filepath = PATH_T_INITIALIZE_P("startfile", "filepath", 0, 0, 0, 0); const wchar_t *operation = NULL; const wchar_t *arguments = NULL; - path_t cwd = PATH_T_INITIALIZE_P("startfile", "cwd", 1, 0, 0); + path_t cwd = PATH_T_INITIALIZE_P("startfile", "cwd", 1, 0, 0, 0); int show_cmd = 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 5, 0, argsbuf); @@ -10364,8 +10384,8 @@ os_getxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE_P("getxattr", "path", 0, 0, 1); - path_t attribute = PATH_T_INITIALIZE_P("getxattr", "attribute", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("getxattr", "path", 0, 0, 0, 1); + path_t attribute = PATH_T_INITIALIZE_P("getxattr", "attribute", 0, 0, 0, 0); int follow_symlinks = 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -10451,8 +10471,8 @@ os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; - path_t path = PATH_T_INITIALIZE_P("setxattr", "path", 0, 0, 1); - path_t attribute = PATH_T_INITIALIZE_P("setxattr", "attribute", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("setxattr", "path", 0, 0, 0, 1); + path_t attribute = PATH_T_INITIALIZE_P("setxattr", "attribute", 0, 0, 0, 0); Py_buffer value = {NULL, NULL}; int flags = 0; int follow_symlinks = 1; @@ -10559,8 +10579,8 @@ os_removexattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; - path_t path = PATH_T_INITIALIZE_P("removexattr", "path", 0, 0, 1); - path_t attribute = PATH_T_INITIALIZE_P("removexattr", "attribute", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("removexattr", "path", 0, 0, 0, 1); + path_t attribute = PATH_T_INITIALIZE_P("removexattr", "attribute", 0, 0, 0, 0); int follow_symlinks = 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); @@ -10645,7 +10665,7 @@ os_listxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - path_t path = PATH_T_INITIALIZE_P("listxattr", "path", 1, 0, 1); + path_t path = PATH_T_INITIALIZE_P("listxattr", "path", 1, 0, 0, 1); int follow_symlinks = 1; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); @@ -11622,7 +11642,7 @@ os_scandir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject * #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - path_t path = PATH_T_INITIALIZE_P("scandir", "path", 1, 0, PATH_HAVE_FDOPENDIR); + path_t path = PATH_T_INITIALIZE_P("scandir", "path", 1, 0, 0, PATH_HAVE_FDOPENDIR); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { @@ -11834,7 +11854,7 @@ os__add_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs, }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE_P("_add_dll_directory", "path", 0, 0, 0); + path_t path = PATH_T_INITIALIZE_P("_add_dll_directory", "path", 0, 0, 0, 0); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -12669,4 +12689,4 @@ os__supports_virtual_terminal(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF #define OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF #endif /* !defined(OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF) */ -/*[clinic end generated code: output=fab60e954c4367e1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=68dd3493b6596cb4 input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index d34e14681ee96e..211f1180785299 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1090,13 +1090,13 @@ get_posix_state(PyObject *module) * * path_converter accepts (Unicode) strings and their * subclasses, and bytes and their subclasses. What - * it does with the argument depends on the platform: + * it does with the argument depends on path.make_wide: * - * * On Windows, if we get a (Unicode) string we - * extract the wchar_t * and return it; if we get - * bytes we decode to wchar_t * and return that. + * * If path.make_wide is nonzero, if we get a (Unicode) + * string we extract the wchar_t * and return it; if we + * get bytes we decode to wchar_t * and return that. * - * * On all other platforms, strings are encoded + * * If path.make_wide is zero, strings are encoded * to bytes using PyUnicode_FSConverter, then we * extract the char * from the bytes object and * return that. @@ -1111,7 +1111,9 @@ get_posix_state(PyObject *module) * path.null_embeddable * If nonzero, the path is permitted to contain embedded null characters. * path.make_wide - * If zero, the path is encoded to bytes. (Argument is ignored on Windows) + * If nonzero, the path is decoded to Unicode, encoded to bytes otherwise. + * path.suppress + * If nonzero, errors are suppressed. * path.allow_fd * If nonzero, the path is permitted to be a file handle * (a signed int) instead of a string. @@ -1127,7 +1129,7 @@ get_posix_state(PyObject *module) * Output fields: * path.wide * Points to the path if it was expressed as Unicode - * and was not encoded. + * or it was bytes and was encoded to Unicode. * path.narrow * Points to the path if it was expressed as bytes, * or it was Unicode and was encoded to bytes. @@ -1140,6 +1142,8 @@ get_posix_state(PyObject *module) * unspecified, path_converter will never get called. * So if you set allow_fd, you *MUST* initialize path.fd = -1 * yourself! + * path.error + * If nonzero, an error occurred. * path.length * The length of the path in characters, if specified as * a string. @@ -1178,30 +1182,32 @@ typedef struct { int nullable; int null_embeddable; int make_wide; + int suppress; int allow_fd; // Output fields const wchar_t *wide; const char *narrow; int fd; + int error; Py_ssize_t length; PyObject *object; PyObject *cleanup; } path_t; #define PATH_T_INITIALIZE(function_name, argument_name, nullable, \ - null_embeddable, make_wide, allow_fd) \ + null_embeddable, make_wide, suppress, allow_fd) \ {function_name, argument_name, nullable, null_embeddable, make_wide, \ - allow_fd, NULL, NULL, -1, 0, NULL, NULL} + suppress, allow_fd, NULL, NULL, -1, 0, 0, NULL, NULL} #ifdef MS_WINDOWS #define PATH_T_INITIALIZE_P(function_name, argument_name, nullable, \ - null_embeddable, allow_fd) \ + null_embeddable, suppress, allow_fd) \ PATH_T_INITIALIZE(function_name, argument_name, nullable, \ - null_embeddable, 1, allow_fd) + null_embeddable, 1, suppress, allow_fd) #else #define PATH_T_INITIALIZE_P(function_name, argument_name, nullable, \ - null_embeddable, allow_fd) \ + null_embeddable, suppress, allow_fd) \ PATH_T_INITIALIZE(function_name, argument_name, nullable, \ - null_embeddable, 0, allow_fd) + null_embeddable, 0, suppress, allow_fd) #endif static void @@ -1390,6 +1396,7 @@ path_converter(PyObject *o, void *p) path->fd = -1; success_exit: + path->error = 0; path->length = length; path->object = o; return Py_CLEANUP_SUPPORTED; @@ -1398,7 +1405,16 @@ path_converter(PyObject *o, void *p) Py_XDECREF(o); Py_XDECREF(bytes); PyMem_Free(wide); - return 0; + if (!path->suppress) { + return 0; + } + path->wide = NULL; + path->narrow = NULL; + path->fd = -1; + path->error = 1; + path->length = 0; + path->object = NULL; + return Py_CLEANUP_SUPPORTED; } static void @@ -2912,8 +2928,8 @@ class path_t_converter(CConverter): converter = 'path_converter' - def converter_init(self, *, allow_fd=False, make_wide=None, - nullable=False, null_embeddable=False): + def converter_init(self, *, allow_fd=False, make_wide=None, nullable=False, + null_embeddable=False, suppress=False): # right now path_t doesn't support default values. # to support a default value, you'll need to override initialize(). if self.default not in (unspecified, None): @@ -2925,6 +2941,7 @@ class path_t_converter(CConverter): self.nullable = nullable self.null_embeddable = null_embeddable self.make_wide = make_wide + self.suppress = suppress self.allow_fd = allow_fd def pre_render(self): @@ -2935,20 +2952,22 @@ class path_t_converter(CConverter): # add self.py_name here when merging with posixmodule conversion if self.make_wide is None: - self.c_default = 'PATH_T_INITIALIZE_P("{}", "{}", {}, {}, {})'.format( + self.c_default = 'PATH_T_INITIALIZE_P("{}", "{}", {}, {}, {}, {})'.format( self.function.name, self.name, strify(self.nullable), strify(self.null_embeddable), + strify(self.suppress), strify(self.allow_fd), ) else: - self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {}, {}, {})'.format( + self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {}, {}, {}, {})'.format( self.function.name, self.name, strify(self.nullable), strify(self.null_embeddable), strify(self.make_wide), + strify(self.suppress), strify(self.allow_fd), ) @@ -3029,7 +3048,7 @@ class sysconf_confname_converter(path_confname_converter): converter="conv_sysconf_confname" [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=fe32fef4a3a19fe5]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=9bfc716d9f7ad345]*/ /*[clinic input] @@ -5104,26 +5123,24 @@ os__path_splitroot_impl(PyObject *module, path_t *path) /*[clinic input] os._path_isdir - s: object + s as path: path_t(suppress=True) Return true if the pathname refers to an existing directory. [clinic start generated code]*/ static PyObject * -os__path_isdir_impl(PyObject *module, PyObject *s) -/*[clinic end generated code: output=9d87ab3c8b8a4e61 input=6e8f9d9f66f85cbc]*/ +os__path_isdir_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=0adeafd60704f710 input=945359aa5bde6f2e]*/ { HANDLE hfile; BOOL close_file = TRUE; FILE_BASIC_INFO info; - path_t _path = PATH_T_INITIALIZE_P("isdir", "s", 0, 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (!path_converter(s, &_path)) { - path_cleanup(&_path); + if (path->error) { if (PyErr_ExceptionMatches(PyExc_ValueError)) { PyErr_Clear(); Py_RETURN_FALSE; @@ -5132,8 +5149,8 @@ os__path_isdir_impl(PyObject *module, PyObject *s) } Py_BEGIN_ALLOW_THREADS - if (_path.wide) { - if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo, + if (path->wide) { + if (_Py_GetFileInformationByName(path->wide, FileStatBasicByNameInfo, &statInfo, sizeof(statInfo))) { if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { slow_path = FALSE; @@ -5148,12 +5165,12 @@ os__path_isdir_impl(PyObject *module, PyObject *s) } } if (slow_path) { - if (_path.fd != -1) { - hfile = _Py_get_osfhandle_noraise(_path.fd); + if (path->fd != -1) { + hfile = _Py_get_osfhandle_noraise(path->fd); close_file = FALSE; } else { - hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL, + hfile = CreateFileW(path->wide, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); } if (hfile != INVALID_HANDLE_VALUE) { @@ -5176,7 +5193,7 @@ os__path_isdir_impl(PyObject *module, PyObject *s) case ERROR_SHARING_VIOLATION: case ERROR_CANT_ACCESS_FILE: case ERROR_INVALID_PARAMETER: - if (STAT(_path.wide, &st)) { + if (STAT(path->wide, &st)) { result = 0; } else { @@ -5190,7 +5207,6 @@ os__path_isdir_impl(PyObject *module, PyObject *s) } Py_END_ALLOW_THREADS - path_cleanup(&_path); if (result) { Py_RETURN_TRUE; } @@ -5201,26 +5217,24 @@ os__path_isdir_impl(PyObject *module, PyObject *s) /*[clinic input] os._path_isfile - path: object + path: path_t(suppress=True) Test whether a path is a regular file [clinic start generated code]*/ static PyObject * -os__path_isfile_impl(PyObject *module, PyObject *path) -/*[clinic end generated code: output=2394ed7c4b5cfd85 input=b37b8017895208b2]*/ +os__path_isfile_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=4f72e7b1ada002da input=f095340c0e8e84e9]*/ { HANDLE hfile; BOOL close_file = TRUE; FILE_BASIC_INFO info; - path_t _path = PATH_T_INITIALIZE_P("isfile", "path", 0, 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (!path_converter(path, &_path)) { - path_cleanup(&_path); + if (path->error) { if (PyErr_ExceptionMatches(PyExc_ValueError)) { PyErr_Clear(); Py_RETURN_FALSE; @@ -5229,8 +5243,8 @@ os__path_isfile_impl(PyObject *module, PyObject *path) } Py_BEGIN_ALLOW_THREADS - if (_path.wide) { - if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo, + if (path->wide) { + if (_Py_GetFileInformationByName(path->wide, FileStatBasicByNameInfo, &statInfo, sizeof(statInfo))) { if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { slow_path = FALSE; @@ -5245,12 +5259,12 @@ os__path_isfile_impl(PyObject *module, PyObject *path) } } if (slow_path) { - if (_path.fd != -1) { - hfile = _Py_get_osfhandle_noraise(_path.fd); + if (path->fd != -1) { + hfile = _Py_get_osfhandle_noraise(path->fd); close_file = FALSE; } else { - hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL, + hfile = CreateFileW(path->wide, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); } if (hfile != INVALID_HANDLE_VALUE) { @@ -5273,7 +5287,7 @@ os__path_isfile_impl(PyObject *module, PyObject *path) case ERROR_SHARING_VIOLATION: case ERROR_CANT_ACCESS_FILE: case ERROR_INVALID_PARAMETER: - if (STAT(_path.wide, &st)) { + if (STAT(path->wide, &st)) { result = 0; } else { @@ -5287,7 +5301,6 @@ os__path_isfile_impl(PyObject *module, PyObject *path) } Py_END_ALLOW_THREADS - path_cleanup(&_path); if (result) { Py_RETURN_TRUE; } @@ -5298,25 +5311,23 @@ os__path_isfile_impl(PyObject *module, PyObject *path) /*[clinic input] os._path_exists - path: object + path: path_t(suppress=True) Test whether a path exists. Returns False for broken symbolic links [clinic start generated code]*/ static PyObject * -os__path_exists_impl(PyObject *module, PyObject *path) -/*[clinic end generated code: output=f508c3b35e13a249 input=d0e5ab7388302942]*/ +os__path_exists_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=69e6089df1fe463a input=ba8bbd209962ca90]*/ { HANDLE hfile; BOOL close_file = TRUE; - path_t _path = PATH_T_INITIALIZE_P("exists", "path", 0, 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (!path_converter(path, &_path)) { - path_cleanup(&_path); + if (path->error) { if (PyErr_ExceptionMatches(PyExc_ValueError)) { PyErr_Clear(); Py_RETURN_FALSE; @@ -5325,8 +5336,8 @@ os__path_exists_impl(PyObject *module, PyObject *path) } Py_BEGIN_ALLOW_THREADS - if (_path.wide) { - if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo, + if (path->wide) { + if (_Py_GetFileInformationByName(path->wide, FileStatBasicByNameInfo, &statInfo, sizeof(statInfo))) { if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { slow_path = FALSE; @@ -5338,12 +5349,12 @@ os__path_exists_impl(PyObject *module, PyObject *path) } } if (slow_path) { - if (_path.fd != -1) { - hfile = _Py_get_osfhandle_noraise(_path.fd); + if (path->fd != -1) { + hfile = _Py_get_osfhandle_noraise(path->fd); close_file = FALSE; } else { - hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL, + hfile = CreateFileW(path->wide, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); } if (hfile != INVALID_HANDLE_VALUE) { @@ -5359,7 +5370,7 @@ os__path_exists_impl(PyObject *module, PyObject *path) case ERROR_SHARING_VIOLATION: case ERROR_CANT_ACCESS_FILE: case ERROR_INVALID_PARAMETER: - if (STAT(_path.wide, &st)) { + if (STAT(path->wide, &st)) { result = 0; } else { @@ -5373,7 +5384,6 @@ os__path_exists_impl(PyObject *module, PyObject *path) } Py_END_ALLOW_THREADS - path_cleanup(&_path); if (result) { Py_RETURN_TRUE; } @@ -5384,26 +5394,24 @@ os__path_exists_impl(PyObject *module, PyObject *path) /*[clinic input] os._path_islink - path: object + path: path_t(suppress=True) Test whether a path is a symbolic link [clinic start generated code]*/ static PyObject * -os__path_islink_impl(PyObject *module, PyObject *path) -/*[clinic end generated code: output=6d8640b1a390c054 input=1a7c08fbe89b1ed6]*/ +os__path_islink_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=109ad77ec747b3b7 input=a59fe6ee2804173f]*/ { HANDLE hfile; BOOL close_file = TRUE; FILE_ATTRIBUTE_TAG_INFO info; - path_t _path = PATH_T_INITIALIZE_P("islink", "path", 0, 0, 1); int result; BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (!path_converter(path, &_path)) { - path_cleanup(&_path); + if (path->error) { if (PyErr_ExceptionMatches(PyExc_ValueError)) { PyErr_Clear(); Py_RETURN_FALSE; @@ -5412,8 +5420,8 @@ os__path_islink_impl(PyObject *module, PyObject *path) } Py_BEGIN_ALLOW_THREADS - if (_path.wide) { - if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo, + if (path->wide) { + if (_Py_GetFileInformationByName(path->wide, FileStatBasicByNameInfo, &statInfo, sizeof(statInfo))) { slow_path = FALSE; if (statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { @@ -5428,12 +5436,12 @@ os__path_islink_impl(PyObject *module, PyObject *path) } } if (slow_path) { - if (_path.fd != -1) { - hfile = _Py_get_osfhandle_noraise(_path.fd); + if (path->fd != -1) { + hfile = _Py_get_osfhandle_noraise(path->fd); close_file = FALSE; } else { - hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL, + hfile = CreateFileW(path->wide, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); @@ -5458,7 +5466,7 @@ os__path_islink_impl(PyObject *module, PyObject *path) case ERROR_SHARING_VIOLATION: case ERROR_CANT_ACCESS_FILE: case ERROR_INVALID_PARAMETER: - if (LSTAT(_path.wide, &st)) { + if (LSTAT(path->wide, &st)) { result = 0; } else { @@ -5472,7 +5480,6 @@ os__path_islink_impl(PyObject *module, PyObject *path) } Py_END_ALLOW_THREADS - path_cleanup(&_path); if (result) { Py_RETURN_TRUE; } From 14d711e7bf386d3cfa1d8e2d7d529ae7a9830634 Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sat, 4 May 2024 07:52:41 +0200 Subject: [PATCH 10/26] Fix `allow_fd` --- Modules/clinic/posixmodule.c.h | 10 +++++----- Modules/posixmodule.c | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index de6c9e2fbd07bb..a74f776a808e9b 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -2056,7 +2056,7 @@ os__path_isdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE_P("_path_isdir", "path", 0, 0, 1, 0); + path_t path = PATH_T_INITIALIZE_P("_path_isdir", "path", 0, 0, 1, 1); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -2120,7 +2120,7 @@ os__path_isfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE_P("_path_isfile", "path", 0, 0, 1, 0); + path_t path = PATH_T_INITIALIZE_P("_path_isfile", "path", 0, 0, 1, 1); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -2184,7 +2184,7 @@ os__path_exists(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE_P("_path_exists", "path", 0, 0, 1, 0); + path_t path = PATH_T_INITIALIZE_P("_path_exists", "path", 0, 0, 1, 1); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -2248,7 +2248,7 @@ os__path_islink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj }; #undef KWTUPLE PyObject *argsbuf[1]; - path_t path = PATH_T_INITIALIZE_P("_path_islink", "path", 0, 0, 1, 0); + path_t path = PATH_T_INITIALIZE_P("_path_islink", "path", 0, 0, 1, 1); args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -12689,4 +12689,4 @@ os__supports_virtual_terminal(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF #define OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF #endif /* !defined(OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF) */ -/*[clinic end generated code: output=68dd3493b6596cb4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=056a1c20f0b1f39f input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 211f1180785299..63c8d6c483dd52 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5123,7 +5123,7 @@ os__path_splitroot_impl(PyObject *module, path_t *path) /*[clinic input] os._path_isdir - s as path: path_t(suppress=True) + s as path: path_t(allow_fd=True, suppress=True) Return true if the pathname refers to an existing directory. @@ -5131,7 +5131,7 @@ Return true if the pathname refers to an existing directory. static PyObject * os__path_isdir_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=0adeafd60704f710 input=945359aa5bde6f2e]*/ +/*[clinic end generated code: output=0adeafd60704f710 input=3f8bf1ea0cc77e0c]*/ { HANDLE hfile; BOOL close_file = TRUE; @@ -5217,7 +5217,7 @@ os__path_isdir_impl(PyObject *module, path_t *path) /*[clinic input] os._path_isfile - path: path_t(suppress=True) + path: path_t(allow_fd=True, suppress=True) Test whether a path is a regular file @@ -5225,7 +5225,7 @@ Test whether a path is a regular file static PyObject * os__path_isfile_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=4f72e7b1ada002da input=f095340c0e8e84e9]*/ +/*[clinic end generated code: output=4f72e7b1ada002da input=b6c69c96e1722a27]*/ { HANDLE hfile; BOOL close_file = TRUE; @@ -5311,7 +5311,7 @@ os__path_isfile_impl(PyObject *module, path_t *path) /*[clinic input] os._path_exists - path: path_t(suppress=True) + path: path_t(allow_fd=True, suppress=True) Test whether a path exists. Returns False for broken symbolic links @@ -5319,7 +5319,7 @@ Test whether a path exists. Returns False for broken symbolic links static PyObject * os__path_exists_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=69e6089df1fe463a input=ba8bbd209962ca90]*/ +/*[clinic end generated code: output=69e6089df1fe463a input=3a73be0affbbe43c]*/ { HANDLE hfile; BOOL close_file = TRUE; @@ -5394,7 +5394,7 @@ os__path_exists_impl(PyObject *module, path_t *path) /*[clinic input] os._path_islink - path: path_t(suppress=True) + path: path_t(allow_fd=True, suppress=True) Test whether a path is a symbolic link @@ -5402,7 +5402,7 @@ Test whether a path is a symbolic link static PyObject * os__path_islink_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=109ad77ec747b3b7 input=a59fe6ee2804173f]*/ +/*[clinic end generated code: output=109ad77ec747b3b7 input=3937a93631697d6c]*/ { HANDLE hfile; BOOL close_file = TRUE; From 89e83fac23549a182af33c70ff8b0ddce7796ea4 Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sat, 4 May 2024 09:20:40 +0200 Subject: [PATCH 11/26] Allow paths of any length --- Modules/posixmodule.c | 59 +++++++++++++++++++++-------------------- Objects/unicodeobject.c | 4 +-- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 63c8d6c483dd52..464d2f92530c05 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1108,8 +1108,9 @@ get_posix_state(PyObject *module) * Input fields: * path.nullable * If nonzero, the path is permitted to be None. - * path.null_embeddable - * If nonzero, the path is permitted to contain embedded null characters. + * path.nonstrict + * If nonzero, the path is permitted to contain + * embedded null characters and have any length. * path.make_wide * If nonzero, the path is decoded to Unicode, encoded to bytes otherwise. * path.suppress @@ -1180,7 +1181,7 @@ typedef struct { const char *function_name; const char *argument_name; int nullable; - int null_embeddable; + int nonstrict; int make_wide; int suppress; int allow_fd; @@ -1194,20 +1195,20 @@ typedef struct { PyObject *cleanup; } path_t; -#define PATH_T_INITIALIZE(function_name, argument_name, nullable, \ - null_embeddable, make_wide, suppress, allow_fd) \ - {function_name, argument_name, nullable, null_embeddable, make_wide, \ - suppress, allow_fd, NULL, NULL, -1, 0, 0, NULL, NULL} +#define PATH_T_INITIALIZE(function_name, argument_name, nullable, nonstrict, \ + make_wide, suppress, allow_fd) \ + {function_name, argument_name, nullable, nonstrict, make_wide, suppress, \ + allow_fd, NULL, NULL, -1, 0, 0, NULL, NULL} #ifdef MS_WINDOWS #define PATH_T_INITIALIZE_P(function_name, argument_name, nullable, \ - null_embeddable, suppress, allow_fd) \ - PATH_T_INITIALIZE(function_name, argument_name, nullable, \ - null_embeddable, 1, suppress, allow_fd) + nonstrict, suppress, allow_fd) \ + PATH_T_INITIALIZE(function_name, argument_name, nullable, nonstrict, 1, \ + suppress, allow_fd) #else #define PATH_T_INITIALIZE_P(function_name, argument_name, nullable, \ - null_embeddable, suppress, allow_fd) \ - PATH_T_INITIALIZE(function_name, argument_name, nullable, \ - null_embeddable, 0, suppress, allow_fd) + nonstrict, suppress, allow_fd) \ + PATH_T_INITIALIZE(function_name, argument_name, nullable, nonstrict, 0, \ + suppress, allow_fd) #endif static void @@ -1300,12 +1301,12 @@ path_converter(PyObject *o, void *p) goto error_exit; } #ifdef MS_WINDOWS - if (length > 32767) { + if (!path->nonstrict && length > 32767) { FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); goto error_exit; } #endif - if (!path->null_embeddable && wcslen(wide) != (size_t)length) { + if (!path->nonstrict && wcslen(wide) != (size_t)length) { FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); goto error_exit; @@ -1317,7 +1318,7 @@ path_converter(PyObject *o, void *p) wide = NULL; goto success_exit; } - if (!_PyUnicode_FSConverter(o, &bytes, path->null_embeddable)) { + if (!_PyUnicode_FSConverter(o, &bytes, path->nonstrict)) { goto error_exit; } } @@ -1349,7 +1350,7 @@ path_converter(PyObject *o, void *p) length = PyBytes_GET_SIZE(bytes); narrow = PyBytes_AS_STRING(bytes); - if (!path->null_embeddable && strlen(narrow) != (size_t)length) { + if (!path->nonstrict && strlen(narrow) != (size_t)length) { FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); goto error_exit; } @@ -1366,12 +1367,12 @@ path_converter(PyObject *o, void *p) goto error_exit; } #ifdef MS_WINDOWS - if (length > 32767) { + if (!path->nonstrict && length > 32767) { FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); goto error_exit; } #endif - if (!path->null_embeddable && wcslen(wide) != (size_t)length) { + if (!path->nonstrict && wcslen(wide) != (size_t)length) { FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); goto error_exit; @@ -2928,8 +2929,8 @@ class path_t_converter(CConverter): converter = 'path_converter' - def converter_init(self, *, allow_fd=False, make_wide=None, nullable=False, - null_embeddable=False, suppress=False): + def converter_init(self, *, allow_fd=False, make_wide=None, + nonstrict=False, nullable=False, suppress=False): # right now path_t doesn't support default values. # to support a default value, you'll need to override initialize(). if self.default not in (unspecified, None): @@ -2939,7 +2940,7 @@ class path_t_converter(CConverter): raise RuntimeError("Can't specify a c_default to the path_t converter!") self.nullable = nullable - self.null_embeddable = null_embeddable + self.nonstrict = nonstrict self.make_wide = make_wide self.suppress = suppress self.allow_fd = allow_fd @@ -2956,7 +2957,7 @@ class path_t_converter(CConverter): self.function.name, self.name, strify(self.nullable), - strify(self.null_embeddable), + strify(self.nonstrict), strify(self.suppress), strify(self.allow_fd), ) @@ -2965,7 +2966,7 @@ class path_t_converter(CConverter): self.function.name, self.name, strify(self.nullable), - strify(self.null_embeddable), + strify(self.nonstrict), strify(self.make_wide), strify(self.suppress), strify(self.allow_fd), @@ -3048,7 +3049,7 @@ class sysconf_confname_converter(path_confname_converter): converter="conv_sysconf_confname" [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=9bfc716d9f7ad345]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=e859625395de8933]*/ /*[clinic input] @@ -5492,7 +5493,7 @@ os__path_islink_impl(PyObject *module, path_t *path) /*[clinic input] os._path_splitroot_ex - path: path_t(null_embeddable=True, make_wide=True) + path: path_t(make_wide=True, nonstrict=True) Split a pathname into drive, root and tail. @@ -5501,7 +5502,7 @@ The tail contains anything after the root. static PyObject * os__path_splitroot_ex_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=4b0072b6cdf4b611 input=fa388b51979a2f57]*/ +/*[clinic end generated code: output=4b0072b6cdf4b611 input=8f29a719fd480028]*/ { Py_ssize_t drvsize, rootsize; PyObject *drv = NULL, *root = NULL, *tail = NULL, *result = NULL; @@ -5538,14 +5539,14 @@ os__path_splitroot_ex_impl(PyObject *module, path_t *path) /*[clinic input] os._path_normpath - path: path_t(null_embeddable=True, make_wide=True) + path: path_t(make_wide=True, nonstrict=True) Normalize path, eliminating double slashes, etc. [clinic start generated code]*/ static PyObject * os__path_normpath_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=d353e7ed9410c044 input=4842c54b2fbdfc83]*/ +/*[clinic end generated code: output=d353e7ed9410c044 input=b8d62d498aa0a8db]*/ { PyObject *result; Py_ssize_t norm_len; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index d100376bdb136c..f9e31a90a74432 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3790,7 +3790,7 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) int -_PyUnicode_FSConverter(PyObject* arg, void* addr, int null_embeddable) +_PyUnicode_FSConverter(PyObject* arg, void* addr, int nonstrict) { PyObject *path = NULL; PyObject *output = NULL; @@ -3819,7 +3819,7 @@ _PyUnicode_FSConverter(PyObject* arg, void* addr, int null_embeddable) size = PyBytes_GET_SIZE(output); data = PyBytes_AS_STRING(output); - if (!null_embeddable && (size_t)size != strlen(data)) { + if (!nonstrict && (size_t)size != strlen(data)) { PyErr_SetString(PyExc_ValueError, "embedded null byte"); Py_DECREF(output); return 0; From d6a174ee657b6d0a5a9920bcd2670344bbdc49ef Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sat, 4 May 2024 09:30:13 +0200 Subject: [PATCH 12/26] Update generated files --- Modules/posixmodule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 464d2f92530c05..4a20e6733f912b 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5502,7 +5502,7 @@ The tail contains anything after the root. static PyObject * os__path_splitroot_ex_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=4b0072b6cdf4b611 input=8f29a719fd480028]*/ +/*[clinic end generated code: output=4b0072b6cdf4b611 input=6eb76e9173412c92]*/ { Py_ssize_t drvsize, rootsize; PyObject *drv = NULL, *root = NULL, *tail = NULL, *result = NULL; @@ -5546,7 +5546,7 @@ Normalize path, eliminating double slashes, etc. static PyObject * os__path_normpath_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=d353e7ed9410c044 input=b8d62d498aa0a8db]*/ +/*[clinic end generated code: output=d353e7ed9410c044 input=3d4ac23b06332dcb]*/ { PyObject *result; Py_ssize_t norm_len; From 4e8b7131c4c2b68bd3d5b1a66506e344bc1ac981 Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sat, 4 May 2024 15:48:48 +0200 Subject: [PATCH 13/26] Simplify bytes conversion Co-authored-by: Eryk Sun --- Modules/posixmodule.c | 10 +++++----- Objects/unicodeobject.c | 10 ++-------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 4a20e6733f912b..c567b88a274fe2 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1096,10 +1096,9 @@ get_posix_state(PyObject *module) * string we extract the wchar_t * and return it; if we * get bytes we decode to wchar_t * and return that. * - * * If path.make_wide is zero, strings are encoded - * to bytes using PyUnicode_FSConverter, then we - * extract the char * from the bytes object and - * return that. + * * If path.make_wide is zero, if we get bytes we extract + * the char_t * and return it; if we get a (Unicode) + * string we encode to char_t * and return that. * * path_converter also optionally accepts signed * integers (representing open file descriptors) instead @@ -1318,7 +1317,8 @@ path_converter(PyObject *o, void *p) wide = NULL; goto success_exit; } - if (!_PyUnicode_FSConverter(o, &bytes, path->nonstrict)) { + bytes = PyUnicode_EncodeFSDefault(o); + if (!bytes) { goto error_exit; } } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index f9e31a90a74432..2c259b7e869efe 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3790,7 +3790,7 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) int -_PyUnicode_FSConverter(PyObject* arg, void* addr, int nonstrict) +PyUnicode_FSConverter(PyObject* arg, void* addr) { PyObject *path = NULL; PyObject *output = NULL; @@ -3819,7 +3819,7 @@ _PyUnicode_FSConverter(PyObject* arg, void* addr, int nonstrict) size = PyBytes_GET_SIZE(output); data = PyBytes_AS_STRING(output); - if (!nonstrict && (size_t)size != strlen(data)) { + if ((size_t)size != strlen(data)) { PyErr_SetString(PyExc_ValueError, "embedded null byte"); Py_DECREF(output); return 0; @@ -3828,12 +3828,6 @@ _PyUnicode_FSConverter(PyObject* arg, void* addr, int nonstrict) return Py_CLEANUP_SUPPORTED; } -int -PyUnicode_FSConverter(PyObject* arg, void* addr) -{ - return _PyUnicode_FSConverter(arg, addr, 0); -} - int PyUnicode_FSDecoder(PyObject* arg, void* addr) From 0777a315209dd14736287ecff98fe88353f7b43f Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sat, 4 May 2024 15:50:09 +0200 Subject: [PATCH 14/26] Remove leftovers --- Include/unicodeobject.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index cdeabee9d7aa68..dee00715b3c51d 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -740,7 +740,6 @@ PyAPI_FUNC(PyObject*) PyUnicode_EncodeLocale( /* ParseTuple converter: encode str objects to bytes using PyUnicode_EncodeFSDefault(); bytes objects are output as-is. */ -extern int _PyUnicode_FSConverter(PyObject*, void*, int); PyAPI_FUNC(int) PyUnicode_FSConverter(PyObject*, void*); /* ParseTuple converter: decode bytes objects to unicode using From 46059d15c5ab4fa590b54169f926e2b7e06364fc Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sat, 4 May 2024 16:33:19 +0200 Subject: [PATCH 15/26] Update conditions to use `PyBytes_Check()` --- Modules/posixmodule.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index c567b88a274fe2..390eceb58380eb 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1378,7 +1378,7 @@ path_converter(PyObject *o, void *p) goto error_exit; } path->wide = wide; - path->narrow = narrow; // TODO: replace by NULL + path->narrow = NULL; Py_DECREF(bytes); wide = NULL; } @@ -1465,11 +1465,7 @@ follow_symlinks_specified(const char *function_name, int follow_symlinks) static int path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd) { - if (!path->wide && (dir_fd != DEFAULT_DIR_FD) -#ifndef MS_WINDOWS - && !path->narrow -#endif - ) { + if (!path->wide && (dir_fd != DEFAULT_DIR_FD) && !path->narrow) { PyErr_Format(PyExc_ValueError, "%s: can't specify dir_fd without matching path", function_name); @@ -4361,13 +4357,14 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) Py_CLEAR(list); goto exit; } + int return_bytes = PyBytes_Check(path->object); do { /* Skip over . and .. */ if (wcscmp(wFileData.cFileName, L".") != 0 && wcscmp(wFileData.cFileName, L"..") != 0) { v = PyUnicode_FromWideChar(wFileData.cFileName, wcslen(wFileData.cFileName)); - if (path->narrow && v) { + if (return_bytes && v) { Py_SETREF(v, PyUnicode_EncodeFSDefault(v)); } if (v == NULL) { @@ -4910,7 +4907,7 @@ os__getfullpathname_impl(PyObject *module, path_t *path) if (str == NULL) { return NULL; } - if (path->narrow) { + if (PyBytes_Check(path->object)) { Py_SETREF(str, PyUnicode_EncodeFSDefault(str)); } return str; @@ -4983,7 +4980,7 @@ os__getfinalpathname_impl(PyObject *module, path_t *path) } result = PyUnicode_FromWideChar(target_path, result_length); - if (result && path->narrow) { + if (result && PyBytes_Check(path->object)) { Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); } @@ -5066,7 +5063,7 @@ os__getvolumepathname_impl(PyObject *module, path_t *path) goto exit; } result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath)); - if (path->narrow) + if (PyBytes_Check(path->object)) Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); exit: @@ -10254,7 +10251,7 @@ os_readlink_impl(PyObject *module, path_t *path, int dir_fd) name[1] = L'\\'; } result = PyUnicode_FromWideChar(name, nameLen); - if (result && path->narrow) { + if (result && PyBytes_Check(path->object)) { Py_SETREF(result, PyUnicode_EncodeFSDefault(result)); } } @@ -15875,7 +15872,8 @@ DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW) entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1); if (!entry->name) goto error; - if (path->narrow) { + int return_bytes = PyBytes_Check(path->object); + if (return_bytes) { Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name)); if (!entry->name) goto error; @@ -15889,7 +15887,7 @@ DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW) PyMem_Free(joined_path); if (!entry->path) goto error; - if (path->narrow) { + if (return_bytes) { Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path)); if (!entry->path) goto error; @@ -15974,7 +15972,7 @@ DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name, goto error; } - if (!path->narrow || !PyBytes_Check(path->object)) { + if (!PyBytes_Check(path->object)) { entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len); if (joined_path) entry->path = PyUnicode_DecodeFSDefault(joined_path); From f95da67c7820e9aa932be98ebffab432ec44399e Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sat, 4 May 2024 16:49:30 +0200 Subject: [PATCH 16/26] Fix access violation attempt 1 --- Modules/posixmodule.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 390eceb58380eb..6e76418814958f 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -4314,7 +4314,7 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) { PyObject *v; HANDLE hFindFile = INVALID_HANDLE_VALUE; - BOOL result; + BOOL result, return_bytes; wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */ /* only claim to have space for MAX_PATH */ Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4; @@ -4326,9 +4326,11 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) if (!path->wide) { /* Default arg: "." */ po_wchars = L"."; len = 1; + return_bytes = 0; } else { po_wchars = path->wide; len = wcslen(path->wide); + return_bytes = PyBytes_Check(path->object); } /* The +5 is so we can append "\\*.*\0" */ wnamebuf = PyMem_New(wchar_t, len + 5); @@ -4357,7 +4359,6 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) Py_CLEAR(list); goto exit; } - int return_bytes = PyBytes_Check(path->object); do { /* Skip over . and .. */ if (wcscmp(wFileData.cFileName, L".") != 0 && From e8ab7d7fe60e74aaec0027f6f1058f6892f08bef Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sat, 4 May 2024 17:04:30 +0200 Subject: [PATCH 17/26] Fix segmentation fault --- Modules/posixmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 6e76418814958f..9c528a7040eb15 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -15973,7 +15973,7 @@ DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name, goto error; } - if (!PyBytes_Check(path->object)) { + if (!name || !PyBytes_Check(path->object)) { entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len); if (joined_path) entry->path = PyUnicode_DecodeFSDefault(joined_path); From 3b21f5daf3fd0380c82e83f55bc3a9c446bd624b Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sat, 4 May 2024 17:17:28 +0200 Subject: [PATCH 18/26] Fix segmentation fault attempt 2 --- Modules/posixmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 9c528a7040eb15..9fb4b3cd2ce1b9 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -15973,7 +15973,7 @@ DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name, goto error; } - if (!name || !PyBytes_Check(path->object)) { + if (!path->narrow || !PyBytes_Check(path->object)) { entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len); if (joined_path) entry->path = PyUnicode_DecodeFSDefault(joined_path); From 7b3a7853156978e11c3052b01233027d505f6dab Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sat, 4 May 2024 17:49:41 +0200 Subject: [PATCH 19/26] Fix access violation attempt 1 --- Modules/posixmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 9fb4b3cd2ce1b9..a1966246365f1e 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -15873,7 +15873,7 @@ DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW) entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1); if (!entry->name) goto error; - int return_bytes = PyBytes_Check(path->object); + int return_bytes = path->wide && PyBytes_Check(path->object); if (return_bytes) { Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name)); if (!entry->name) From a94c852894a5c64219a819e1f867e9e6730f761f Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sat, 4 May 2024 17:57:32 +0200 Subject: [PATCH 20/26] Clear ValueError Co-authored-by: Eryk Sun --- Modules/posixmodule.c | 94 +++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 53 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index a1966246365f1e..6da26822e81b7f 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1112,8 +1112,8 @@ get_posix_state(PyObject *module) * embedded null characters and have any length. * path.make_wide * If nonzero, the path is decoded to Unicode, encoded to bytes otherwise. - * path.suppress - * If nonzero, errors are suppressed. + * path.suppress_value_error + * If nonzero, ValueErrors are suppressed. * path.allow_fd * If nonzero, the path is permitted to be a file handle * (a signed int) instead of a string. @@ -1142,8 +1142,8 @@ get_posix_state(PyObject *module) * unspecified, path_converter will never get called. * So if you set allow_fd, you *MUST* initialize path.fd = -1 * yourself! - * path.error - * If nonzero, an error occurred. + * path.value_error + * If nonzero, a ValueError occurred. * path.length * The length of the path in characters, if specified as * a string. @@ -1182,32 +1182,32 @@ typedef struct { int nullable; int nonstrict; int make_wide; - int suppress; + int suppress_value_error; int allow_fd; // Output fields const wchar_t *wide; const char *narrow; int fd; - int error; + int value_error; Py_ssize_t length; PyObject *object; PyObject *cleanup; } path_t; #define PATH_T_INITIALIZE(function_name, argument_name, nullable, nonstrict, \ - make_wide, suppress, allow_fd) \ - {function_name, argument_name, nullable, nonstrict, make_wide, suppress, \ - allow_fd, NULL, NULL, -1, 0, 0, NULL, NULL} + make_wide, suppress_value_error, allow_fd) \ + {function_name, argument_name, nullable, nonstrict, make_wide, \ + suppress_value_error, allow_fd, NULL, NULL, -1, 0, 0, NULL, NULL} #ifdef MS_WINDOWS #define PATH_T_INITIALIZE_P(function_name, argument_name, nullable, \ - nonstrict, suppress, allow_fd) \ + nonstrict, suppress_value_error, allow_fd) \ PATH_T_INITIALIZE(function_name, argument_name, nullable, nonstrict, 1, \ - suppress, allow_fd) + suppress_value_error, allow_fd) #else #define PATH_T_INITIALIZE_P(function_name, argument_name, nullable, \ - nonstrict, suppress, allow_fd) \ + nonstrict, suppress_value_error, allow_fd) \ PATH_T_INITIALIZE(function_name, argument_name, nullable, nonstrict, 0, \ - suppress, allow_fd) + suppress_value_error, allow_fd) #endif static void @@ -1397,7 +1397,7 @@ path_converter(PyObject *o, void *p) path->fd = -1; success_exit: - path->error = 0; + path->value_error = 0; path->length = length; path->object = o; return Py_CLEANUP_SUPPORTED; @@ -1406,13 +1406,16 @@ path_converter(PyObject *o, void *p) Py_XDECREF(o); Py_XDECREF(bytes); PyMem_Free(wide); - if (!path->suppress) { + if (!path->suppress_value_error || + !PyErr_ExceptionMatches(PyExc_ValueError)) + { return 0; } + PyErr_Clear(); path->wide = NULL; path->narrow = NULL; path->fd = -1; - path->error = 1; + path->value_error = 1; path->length = 0; path->object = NULL; return Py_CLEANUP_SUPPORTED; @@ -2926,7 +2929,8 @@ class path_t_converter(CConverter): converter = 'path_converter' def converter_init(self, *, allow_fd=False, make_wide=None, - nonstrict=False, nullable=False, suppress=False): + nonstrict=False, nullable=False, + suppress_value_error=False): # right now path_t doesn't support default values. # to support a default value, you'll need to override initialize(). if self.default not in (unspecified, None): @@ -2938,7 +2942,7 @@ class path_t_converter(CConverter): self.nullable = nullable self.nonstrict = nonstrict self.make_wide = make_wide - self.suppress = suppress + self.suppress_value_error = suppress_value_error self.allow_fd = allow_fd def pre_render(self): @@ -2954,7 +2958,7 @@ class path_t_converter(CConverter): self.name, strify(self.nullable), strify(self.nonstrict), - strify(self.suppress), + strify(self.suppress_value_error), strify(self.allow_fd), ) else: @@ -2964,7 +2968,7 @@ class path_t_converter(CConverter): strify(self.nullable), strify(self.nonstrict), strify(self.make_wide), - strify(self.suppress), + strify(self.suppress_value_error), strify(self.allow_fd), ) @@ -3045,7 +3049,7 @@ class sysconf_confname_converter(path_confname_converter): converter="conv_sysconf_confname" [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=e859625395de8933]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=577cb476e5d64960]*/ /*[clinic input] @@ -5122,7 +5126,7 @@ os__path_splitroot_impl(PyObject *module, path_t *path) /*[clinic input] os._path_isdir - s as path: path_t(allow_fd=True, suppress=True) + s as path: path_t(allow_fd=True, suppress_value_error=True) Return true if the pathname refers to an existing directory. @@ -5130,7 +5134,7 @@ Return true if the pathname refers to an existing directory. static PyObject * os__path_isdir_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=0adeafd60704f710 input=3f8bf1ea0cc77e0c]*/ +/*[clinic end generated code: output=0adeafd60704f710 input=2d09b8801fd2f638]*/ { HANDLE hfile; BOOL close_file = TRUE; @@ -5139,12 +5143,8 @@ os__path_isdir_impl(PyObject *module, path_t *path) BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (path->error) { - if (PyErr_ExceptionMatches(PyExc_ValueError)) { - PyErr_Clear(); - Py_RETURN_FALSE; - } - return NULL; + if (path->value_error) { + Py_RETURN_FALSE; } Py_BEGIN_ALLOW_THREADS @@ -5216,7 +5216,7 @@ os__path_isdir_impl(PyObject *module, path_t *path) /*[clinic input] os._path_isfile - path: path_t(allow_fd=True, suppress=True) + path: path_t(allow_fd=True, suppress_value_error=True) Test whether a path is a regular file @@ -5224,7 +5224,7 @@ Test whether a path is a regular file static PyObject * os__path_isfile_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=4f72e7b1ada002da input=b6c69c96e1722a27]*/ +/*[clinic end generated code: output=4f72e7b1ada002da input=c378f54b14ae878a]*/ { HANDLE hfile; BOOL close_file = TRUE; @@ -5233,12 +5233,8 @@ os__path_isfile_impl(PyObject *module, path_t *path) BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (path->error) { - if (PyErr_ExceptionMatches(PyExc_ValueError)) { - PyErr_Clear(); - Py_RETURN_FALSE; - } - return NULL; + if (path->value_error) { + Py_RETURN_FALSE; } Py_BEGIN_ALLOW_THREADS @@ -5310,7 +5306,7 @@ os__path_isfile_impl(PyObject *module, path_t *path) /*[clinic input] os._path_exists - path: path_t(allow_fd=True, suppress=True) + path: path_t(allow_fd=True, suppress_value_error=True) Test whether a path exists. Returns False for broken symbolic links @@ -5318,7 +5314,7 @@ Test whether a path exists. Returns False for broken symbolic links static PyObject * os__path_exists_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=69e6089df1fe463a input=3a73be0affbbe43c]*/ +/*[clinic end generated code: output=69e6089df1fe463a input=a62c424c1784c43b]*/ { HANDLE hfile; BOOL close_file = TRUE; @@ -5326,12 +5322,8 @@ os__path_exists_impl(PyObject *module, path_t *path) BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (path->error) { - if (PyErr_ExceptionMatches(PyExc_ValueError)) { - PyErr_Clear(); - Py_RETURN_FALSE; - } - return NULL; + if (path->value_error) { + Py_RETURN_FALSE; } Py_BEGIN_ALLOW_THREADS @@ -5393,7 +5385,7 @@ os__path_exists_impl(PyObject *module, path_t *path) /*[clinic input] os._path_islink - path: path_t(allow_fd=True, suppress=True) + path: path_t(allow_fd=True, suppress_value_error=True) Test whether a path is a symbolic link @@ -5401,7 +5393,7 @@ Test whether a path is a symbolic link static PyObject * os__path_islink_impl(PyObject *module, path_t *path) -/*[clinic end generated code: output=109ad77ec747b3b7 input=3937a93631697d6c]*/ +/*[clinic end generated code: output=109ad77ec747b3b7 input=80bd45abdecb418e]*/ { HANDLE hfile; BOOL close_file = TRUE; @@ -5410,12 +5402,8 @@ os__path_islink_impl(PyObject *module, path_t *path) BOOL slow_path = TRUE; FILE_STAT_BASIC_INFORMATION statInfo; - if (path->error) { - if (PyErr_ExceptionMatches(PyExc_ValueError)) { - PyErr_Clear(); - Py_RETURN_FALSE; - } - return NULL; + if (path->value_error) { + Py_RETURN_FALSE; } Py_BEGIN_ALLOW_THREADS From 5f717c9f59637a91c53248cd48ce360d5867fcbe Mon Sep 17 00:00:00 2001 From: Nice Zombies Date: Sat, 4 May 2024 18:55:34 +0200 Subject: [PATCH 21/26] Apply suggestions from code review Co-authored-by: Eryk Sun --- Modules/posixmodule.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 6da26822e81b7f..52e83b49614d7f 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1111,9 +1111,11 @@ get_posix_state(PyObject *module) * If nonzero, the path is permitted to contain * embedded null characters and have any length. * path.make_wide - * If nonzero, the path is decoded to Unicode, encoded to bytes otherwise. + * If nonzero, the converter always uses wide, decoding if necessary, else + * it always uses narrow, encoding if necessary. The default value is + * nonzero on Windows, else zero. * path.suppress_value_error - * If nonzero, ValueErrors are suppressed. + * If nonzero, raising ValueError is suppressed. * path.allow_fd * If nonzero, the path is permitted to be a file handle * (a signed int) instead of a string. @@ -1129,10 +1131,10 @@ get_posix_state(PyObject *module) * Output fields: * path.wide * Points to the path if it was expressed as Unicode - * or it was bytes and was encoded to Unicode. + * or if it was bytes and decoded to Unicode. * path.narrow * Points to the path if it was expressed as bytes, - * or it was Unicode and was encoded to bytes. + * or if it was Unicode and encoded to bytes. * path.fd * Contains a file descriptor if path.accept_fd was true * and the caller provided a signed integer instead of any @@ -1143,7 +1145,8 @@ get_posix_state(PyObject *module) * So if you set allow_fd, you *MUST* initialize path.fd = -1 * yourself! * path.value_error - * If nonzero, a ValueError occurred. + * If nonzero, then suppress_value_error was specified and a ValueError + * occurred. * path.length * The length of the path in characters, if specified as * a string. From b76774bbfb6774a487e6a34d32f78e3b45deb3fe Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sat, 4 May 2024 19:35:25 +0200 Subject: [PATCH 22/26] Same docstring for python fallback --- Lib/ntpath.py | 13 +++---------- Lib/posixpath.py | 12 +++--------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 9375b05d7027ee..1236730dd801f7 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -171,16 +171,9 @@ def splitdrive(p): from nt import _path_splitroot_ex as splitroot except ImportError: def splitroot(p): - """Split a pathname into drive, root and tail. The drive is defined - exactly as in splitdrive(). On Windows, the root may be a single path - separator or an empty string. The tail contains anything after the root. - For example: - - splitroot('//server/share/') == ('//server/share', '/', '') - splitroot('C:/Users/Barney') == ('C:', '/', 'Users/Barney') - splitroot('C:///spam///ham') == ('C:', '/', '//spam///ham') - splitroot('Windows/notepad') == ('', '', 'Windows/notepad') - """ + """Split a pathname into drive, root and tail. + + The tail contains anything after the root.""" p = os.fspath(p) if isinstance(p, bytes): sep = b'\\' diff --git a/Lib/posixpath.py b/Lib/posixpath.py index bad1746ccb4f19..01268e47543f2f 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -138,15 +138,9 @@ def splitdrive(p): from posix import _path_splitroot_ex as splitroot except ImportError: def splitroot(p): - """Split a pathname into drive, root and tail. On Posix, drive is always - empty; the root may be empty, a single slash, or two slashes. The tail - contains anything after the root. For example: - - splitroot('foo/bar') == ('', '', 'foo/bar') - splitroot('/foo/bar') == ('', '/', 'foo/bar') - splitroot('//foo/bar') == ('', '//', 'foo/bar') - splitroot('///foo/bar') == ('', '/', '//foo/bar') - """ + """Split a pathname into drive, root and tail. + + The tail contains anything after the root.""" p = os.fspath(p) if isinstance(p, bytes): sep = b'/' From f2537a12e880b557c70f1c340554b03ded18499a Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Sat, 4 May 2024 19:40:49 +0200 Subject: [PATCH 23/26] Revert newline --- Lib/ntpath.py | 1 - Lib/posixpath.py | 1 - 2 files changed, 2 deletions(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 1236730dd801f7..8f8dd8d408d66b 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -215,7 +215,6 @@ def splitroot(p): return empty, empty, p - # Split a path in head (everything up to the last '/') and tail (the # rest). After the trailing '/' is stripped, the invariant # join(head, tail) == p holds. diff --git a/Lib/posixpath.py b/Lib/posixpath.py index 01268e47543f2f..3d67338ab275f6 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -160,7 +160,6 @@ def splitroot(p): return empty, p[:2], p[2:] - # Return the tail (basename) part of a path, same as split(path)[1]. def basename(p): From 360326d3848ecf2930271866f6b1e013977b618f Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Wed, 22 May 2024 09:55:44 +0200 Subject: [PATCH 24/26] Fix pointers --- Modules/posixmodule.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 27aa6a7a30e053..2be8962af96d96 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5371,7 +5371,7 @@ static int os__path_exists_impl(PyObject *module, path_t *path) /*[clinic end generated code: output=8da13acf666e16ba input=29198507a6082a57]*/ { - return _testFileExists(&path, TRUE); + return _testFileExists(path, TRUE); } @@ -5389,7 +5389,7 @@ static int os__path_lexists_impl(PyObject *module, path_t *path) /*[clinic end generated code: output=e7240ed5fc45bff3 input=03d9fed8bc6ce96f]*/ { - return _testFileExists(&path, FALSE); + return _testFileExists(path, FALSE); } @@ -5406,7 +5406,7 @@ static int os__path_isdir_impl(PyObject *module, path_t *path) /*[clinic end generated code: output=d5786196f9e2fa7a input=132a3b5301aecf79]*/ { - return _testFileType(&path, PY_IFDIR); + return _testFileType(path, PY_IFDIR); } @@ -5423,7 +5423,7 @@ static int os__path_isfile_impl(PyObject *module, path_t *path) /*[clinic end generated code: output=5c3073bc212b9863 input=4ac1fd350b30a39e]*/ { - return _testFileType(&path, PY_IFREG); + return _testFileType(path, PY_IFREG); } @@ -5440,7 +5440,7 @@ static int os__path_islink_impl(PyObject *module, path_t *path) /*[clinic end generated code: output=30da7bda8296adcc input=7510ce05b547debb]*/ { - return _testFileType(&path, PY_IFLNK); + return _testFileType(path, PY_IFLNK); } @@ -5457,7 +5457,7 @@ static int os__path_isjunction_impl(PyObject *module, path_t *path) /*[clinic end generated code: output=e1d17a9dd18a9945 input=7dcb8bc4e972fcaf]*/ { - return _testFileType(&path, PY_IFMNT); + return _testFileType(path, PY_IFMNT); } #undef PY_IFREG From 3514bdba1e0c3a2d7df2e5af48390102b323e525 Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Wed, 22 May 2024 10:48:19 +0200 Subject: [PATCH 25/26] Return false in case of value error --- Modules/posixmodule.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 2be8962af96d96..9f0320aa4047e8 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5307,12 +5307,12 @@ _testFileExistsByName(LPCWSTR path, BOOL followLinks) } -static int +static BOOL _testFileExists(path_t *path, BOOL followLinks) { BOOL result = FALSE; if (path->value_error) { - return -1; + return FALSE; } Py_BEGIN_ALLOW_THREADS @@ -5333,12 +5333,12 @@ _testFileExists(path_t *path, BOOL followLinks) } -static int +static BOOL _testFileType(path_t *path, int testedType) { BOOL result = FALSE; if (path->value_error) { - return -1; + return FALSE; } Py_BEGIN_ALLOW_THREADS From e362054a2715defb44a86761502def0555b4c915 Mon Sep 17 00:00:00 2001 From: Nineteendo Date: Fri, 24 May 2024 16:08:24 +0200 Subject: [PATCH 26/26] Add null check --- Modules/posixmodule.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 9f0320aa4047e8..bb35cfd9cdb138 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -5504,8 +5504,17 @@ os__path_splitroot_ex_impl(PyObject *module, path_t *path) } if (PyBytes_Check(path->object)) { Py_SETREF(drv, PyUnicode_EncodeFSDefault(drv)); + if (drv == NULL) { + goto exit; + } Py_SETREF(root, PyUnicode_EncodeFSDefault(root)); + if (root == NULL) { + goto exit; + } Py_SETREF(tail, PyUnicode_EncodeFSDefault(tail)); + if (tail == NULL) { + goto exit; + } } result = PyTuple_Pack(3, drv, root, tail); exit: pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy