]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
On Unix, avoid a conversion to wchar_t in getpath.c (#153230)
authorVictor Stinner <vstinner@python.org>
Tue, 7 Jul 2026 16:28:05 +0000 (18:28 +0200)
committerGitHub <noreply@github.com>
Tue, 7 Jul 2026 16:28:05 +0000 (18:28 +0200)
* Replace _Py_wstat() with _Py_stat() in isfile() and isxfile().
* Replace _Py_wfopen() with Py_fopen() in readlines().

Modules/getpath.c
Python/fileutils.c

index 0c80678a678dc8bc3ea0da083625a98a3b3e6f9a..ed41536acbcc813c45a01691a1719ab98dcba0b6 100644 (file)
@@ -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;
index 0c1766b88045002d25cbf207006f118739c55a1b..98ed66eff94ee10fd83fb02fe0d5fb6e1a061855 100644 (file)
@@ -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
 }