bpo-36346: Make using the legacy Unicode C API optional (GH-21437)
Add compile time option USE_UNICODE_WCHAR_CACHE. Setting it to 0
makes the interpreter not using the wchar_t cache and the legacy Unicode C API.
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index a411f28..efd9954 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -988,6 +988,11 @@
static void
path_cleanup(path_t *path)
{
+#if !USE_UNICODE_WCHAR_CACHE
+ wchar_t *wide = (wchar_t *)path->wide;
+ path->wide = NULL;
+ PyMem_Free(wide);
+#endif /* USE_UNICODE_WCHAR_CACHE */
Py_CLEAR(path->object);
Py_CLEAR(path->cleanup);
}
@@ -1002,7 +1007,7 @@
const char *narrow;
#ifdef MS_WINDOWS
PyObject *wo = NULL;
- const wchar_t *wide;
+ wchar_t *wide = NULL;
#endif
#define FORMAT_EXCEPTION(exc, fmt) \
@@ -1075,7 +1080,14 @@
if (is_unicode) {
#ifdef MS_WINDOWS
+#if USE_UNICODE_WCHAR_CACHE
+_Py_COMP_DIAG_PUSH
+_Py_COMP_DIAG_IGNORE_DEPR_DECLS
wide = PyUnicode_AsUnicodeAndSize(o, &length);
+_Py_COMP_DIAG_POP
+#else /* USE_UNICODE_WCHAR_CACHE */
+ wide = PyUnicode_AsWideCharString(o, &length);
+#endif /* USE_UNICODE_WCHAR_CACHE */
if (!wide) {
goto error_exit;
}
@@ -1091,6 +1103,9 @@
path->wide = wide;
path->narrow = FALSE;
path->fd = -1;
+#if !USE_UNICODE_WCHAR_CACHE
+ wide = NULL;
+#endif /* USE_UNICODE_WCHAR_CACHE */
goto success_exit;
#else
if (!PyUnicode_FSConverter(o, &bytes)) {
@@ -1166,7 +1181,15 @@
goto error_exit;
}
+#if USE_UNICODE_WCHAR_CACHE
+_Py_COMP_DIAG_PUSH
+_Py_COMP_DIAG_IGNORE_DEPR_DECLS
wide = PyUnicode_AsUnicodeAndSize(wo, &length);
+_Py_COMP_DIAG_POP
+#else /* USE_UNICODE_WCHAR_CACHE */
+ wide = PyUnicode_AsWideCharString(wo, &length);
+ Py_DECREF(wo);
+#endif /* USE_UNICODE_WCHAR_CACHE */
if (!wide) {
goto error_exit;
}
@@ -1180,8 +1203,12 @@
}
path->wide = wide;
path->narrow = TRUE;
- path->cleanup = wo;
Py_DECREF(bytes);
+#if USE_UNICODE_WCHAR_CACHE
+ path->cleanup = wo;
+#else /* USE_UNICODE_WCHAR_CACHE */
+ wide = NULL;
+#endif /* USE_UNICODE_WCHAR_CACHE */
#else
path->wide = NULL;
path->narrow = narrow;
@@ -1205,7 +1232,11 @@
Py_XDECREF(o);
Py_XDECREF(bytes);
#ifdef MS_WINDOWS
+#if USE_UNICODE_WCHAR_CACHE
Py_XDECREF(wo);
+#else /* USE_UNICODE_WCHAR_CACHE */
+ PyMem_Free(wide);
+#endif /* USE_UNICODE_WCHAR_CACHE */
#endif
return 0;
}
@@ -12824,7 +12855,15 @@
#ifdef MS_WINDOWS
if (!PyUnicode_FSDecoder(self->path, &ub))
return NULL;
+#if USE_UNICODE_WCHAR_CACHE
+_Py_COMP_DIAG_PUSH
+_Py_COMP_DIAG_IGNORE_DEPR_DECLS
const wchar_t *path = PyUnicode_AsUnicode(ub);
+_Py_COMP_DIAG_POP
+#else /* USE_UNICODE_WCHAR_CACHE */
+ wchar_t *path = PyUnicode_AsWideCharString(ub, NULL);
+ Py_DECREF(ub);
+#endif /* USE_UNICODE_WCHAR_CACHE */
#else /* POSIX */
if (!PyUnicode_FSConverter(self->path, &ub))
return NULL;
@@ -12834,6 +12873,7 @@
result = fstatat(self->dir_fd, path, &st,
follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
#else
+ Py_DECREF(ub);
PyErr_SetString(PyExc_NotImplementedError, "can't fetch stat");
return NULL;
#endif /* HAVE_FSTATAT */
@@ -12846,7 +12886,11 @@
else
result = LSTAT(path, &st);
}
+#if defined(MS_WINDOWS) && !USE_UNICODE_WCHAR_CACHE
+ PyMem_Free(path);
+#else /* USE_UNICODE_WCHAR_CACHE */
Py_DECREF(ub);
+#endif /* USE_UNICODE_WCHAR_CACHE */
if (result != 0)
return path_object_error(self->path);
@@ -13035,15 +13079,24 @@
#ifdef MS_WINDOWS
if (!self->got_file_index) {
PyObject *unicode;
- const wchar_t *path;
STRUCT_STAT stat;
int result;
if (!PyUnicode_FSDecoder(self->path, &unicode))
return NULL;
- path = PyUnicode_AsUnicode(unicode);
+#if USE_UNICODE_WCHAR_CACHE
+_Py_COMP_DIAG_PUSH
+_Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ const wchar_t *path = PyUnicode_AsUnicode(unicode);
result = LSTAT(path, &stat);
Py_DECREF(unicode);
+_Py_COMP_DIAG_POP
+#else /* USE_UNICODE_WCHAR_CACHE */
+ wchar_t *path = PyUnicode_AsWideCharString(unicode, NULL);
+ Py_DECREF(unicode);
+ result = LSTAT(path, &stat);
+ PyMem_Free(path);
+#endif /* USE_UNICODE_WCHAR_CACHE */
if (result != 0)
return path_object_error(self->path);
@@ -13597,10 +13650,9 @@
iterator->dirp = NULL;
#endif
- memcpy(&iterator->path, path, sizeof(path_t));
/* Move the ownership to iterator->path */
- path->object = NULL;
- path->cleanup = NULL;
+ memcpy(&iterator->path, path, sizeof(path_t));
+ memset(path, 0, sizeof(path_t));
#ifdef MS_WINDOWS
iterator->first_time = 1;
@@ -13622,9 +13674,9 @@
#else /* POSIX */
errno = 0;
#ifdef HAVE_FDOPENDIR
- if (path->fd != -1) {
+ if (iterator->path.fd != -1) {
/* closedir() closes the FD, so we duplicate it */
- fd = _Py_dup(path->fd);
+ fd = _Py_dup(iterator->path.fd);
if (fd == -1)
goto error;