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.
This commit is contained in:
Serhiy Storchaka 2020-07-10 23:26:06 +03:00 committed by GitHub
parent 9650fe0197
commit 4c8f09d7ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 360 additions and 99 deletions

View file

@ -988,6 +988,11 @@ typedef struct {
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 @@ path_converter(PyObject *o, void *p)
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 @@ path_converter(PyObject *o, void *p)
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_converter(PyObject *o, void *p)
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 @@ path_converter(PyObject *o, void *p)
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_converter(PyObject *o, void *p)
}
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 @@ path_converter(PyObject *o, void *p)
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 @@ DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
#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 @@ DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
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 @@ DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
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 @@ os_DirEntry_inode_impl(DirEntry *self)
#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 @@ os_scandir_impl(PyObject *module, path_t *path)
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 @@ os_scandir_impl(PyObject *module, path_t *path)
#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;