https://github.com/python/cpython/commit/ce96dd68589f4cff54aa7bb7bb0991c1ef7d2f4b
commit: ce96dd68589f4cff54aa7bb7bb0991c1ef7d2f4b
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2026-07-07T18:28:05+02:00
summary:
On Unix, avoid a conversion to wchar_t in getpath.c (#153230)
* Replace _Py_wstat() with _Py_stat() in isfile() and isxfile().
* Replace _Py_wfopen() with Py_fopen() in readlines().
files:
M Modules/getpath.c
M Python/fileutils.c
diff --git a/Modules/getpath.c b/Modules/getpath.c
index 0c80678a678dc8..ed41536acbcc81 100644
--- a/Modules/getpath.c
+++ b/Modules/getpath.c
@@ -198,57 +198,67 @@ getpath_isdir(PyObject *Py_UNUSED(self), PyObject *args)
static PyObject *
getpath_isfile(PyObject *Py_UNUSED(self), PyObject *args)
{
- PyObject *r = NULL;
PyObject *pathobj;
- const wchar_t *path;
if (!PyArg_ParseTuple(args, "U", &pathobj)) {
return NULL;
}
- path = PyUnicode_AsWideCharString(pathobj, NULL);
- if (path) {
+
+ int isfile;
#ifdef MS_WINDOWS
- DWORD attr = GetFileAttributesW(path);
- r = (attr != INVALID_FILE_ATTRIBUTES) &&
- !(attr & FILE_ATTRIBUTE_DIRECTORY) ? Py_True : Py_False;
+ wchar_t *path = PyUnicode_AsWideCharString(pathobj, NULL);
+ if (path == NULL) {
+ return NULL;
+ }
+
+ DWORD attr = GetFileAttributesW(path);
+ PyMem_Free(path);
+ isfile = ((attr != INVALID_FILE_ATTRIBUTES)
+ && !(attr & FILE_ATTRIBUTE_DIRECTORY));
#else
- struct stat st;
- r = (_Py_wstat(path, &st) == 0) && S_ISREG(st.st_mode) ? Py_True :
Py_False;
-#endif
- PyMem_Free((void *)path);
+ struct stat st;
+ int res = _Py_stat(pathobj, &st);
+ if (res == -2) {
+ return NULL;
}
- return Py_XNewRef(r);
+ isfile = ((res == 0) && S_ISREG(st.st_mode));
+#endif
+ return PyBool_FromLong(isfile);
}
static PyObject *
getpath_isxfile(PyObject *Py_UNUSED(self), PyObject *args)
{
- PyObject *r = NULL;
PyObject *pathobj;
- const wchar_t *path;
- Py_ssize_t cchPath;
if (!PyArg_ParseTuple(args, "U", &pathobj)) {
return NULL;
}
- path = PyUnicode_AsWideCharString(pathobj, &cchPath);
- if (path) {
+
+ int isxfile;
#ifdef MS_WINDOWS
- DWORD attr = GetFileAttributesW(path);
- r = (attr != INVALID_FILE_ATTRIBUTES) &&
- !(attr & FILE_ATTRIBUTE_DIRECTORY) &&
- (cchPath >= 4) &&
- (CompareStringOrdinal(path + cchPath - 4, -1, L".exe", -1, 1 /*
ignore case */) == CSTR_EQUAL)
- ? Py_True : Py_False;
+ Py_ssize_t cchPath;
+ wchar_t *path = PyUnicode_AsWideCharString(pathobj, &cchPath);
+ if (path == NULL) {
+ return NULL;
+ }
+
+ DWORD attr = GetFileAttributesW(path);
+ PyMem_Free(path);
+ isxfile = (attr != INVALID_FILE_ATTRIBUTES) &&
+ !(attr & FILE_ATTRIBUTE_DIRECTORY) &&
+ (cchPath >= 4) &&
+ (CompareStringOrdinal(path + cchPath - 4, -1, L".exe", -1, 1 /*
ignore case */) == CSTR_EQUAL);
#else
- struct stat st;
- r = (_Py_wstat(path, &st) == 0) &&
- S_ISREG(st.st_mode) &&
- (st.st_mode & 0111)
- ? Py_True : Py_False;
-#endif
- PyMem_Free((void *)path);
+ struct stat st;
+ int res = _Py_stat(pathobj, &st);
+ if (res == -2) {
+ return NULL;
}
- return Py_XNewRef(r);
+ isxfile = ((res == 0)
+ && S_ISREG(st.st_mode)
+ && (st.st_mode & 0111));
+#endif
+ return PyBool_FromLong(isxfile);
}
@@ -340,25 +350,16 @@ getpath_joinpath(PyObject *Py_UNUSED(self), PyObject
*args)
static PyObject *
getpath_readlines(PyObject *Py_UNUSED(self), PyObject *args)
{
- PyObject *r = NULL;
PyObject *pathobj;
- const wchar_t *path;
if (!PyArg_ParseTuple(args, "U", &pathobj)) {
return NULL;
}
- path = PyUnicode_AsWideCharString(pathobj, NULL);
- if (!path) {
- return NULL;
- }
- FILE *fp = _Py_wfopen(path, L"rb");
+ FILE *fp = Py_fopen(pathobj, "rb");
if (!fp) {
- PyErr_SetFromErrno(PyExc_OSError);
- PyMem_Free((void *)path);
return NULL;
}
- PyMem_Free((void *)path);
- r = PyList_New(0);
+ PyObject *r = PyList_New(0);
if (!r) {
fclose(fp);
return NULL;
diff --git a/Python/fileutils.c b/Python/fileutils.c
index 0c1766b8804500..98ed66eff94ee1 100644
--- a/Python/fileutils.c
+++ b/Python/fileutils.c
@@ -1368,22 +1368,21 @@ _Py_stat(PyObject *path, struct stat *statbuf)
PyMem_Free(wpath);
return err;
#else
- int ret;
- PyObject *bytes;
- char *cpath;
-
- bytes = PyUnicode_EncodeFSDefault(path);
- if (bytes == NULL)
+ PyObject *bytes = PyUnicode_EncodeFSDefault(path);
+ if (bytes == NULL) {
return -2;
+ }
/* check for embedded null bytes */
+ char *cpath;
if (PyBytes_AsStringAndSize(bytes, &cpath, NULL) == -1) {
Py_DECREF(bytes);
return -2;
}
- ret = stat(cpath, statbuf);
+ int ret = stat(cpath, statbuf);
Py_DECREF(bytes);
+ assert(ret == 0 || ret == -1);
return ret;
#endif
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]