From 2289181b9793279fa0a3b293c2afd737f8fa4209 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Fri, 10 Dec 2021 16:05:45 +0100 Subject: [PATCH 1/5] bpo-45653: Freeze parts of the encodings package Signed-off-by: Christian Heimes Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> --- Makefile.pre.in | 36 +++++++++++++ .../2021-12-10-16-06-13.bpo-45653.FQo2rA.rst | 1 + PCbuild/_freeze_module.vcxproj | 28 +++++++++++ PCbuild/_freeze_module.vcxproj.filters | 12 +++++ PCbuild/pythoncore.vcxproj | 4 ++ Python/codecs.c | 50 +++++++++++++++++++ Python/frozen.c | 12 +++++ Tools/scripts/freeze_modules.py | 8 +-- 8 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2021-12-10-16-06-13.bpo-45653.FQo2rA.rst diff --git a/Makefile.pre.in b/Makefile.pre.in index fbd4c3a23fd81b..eda8917977110f 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -486,6 +486,10 @@ DEEPFREEZE_OBJS = \ Python/deepfreeze/zipimport.o \ Python/deepfreeze/abc.o \ Python/deepfreeze/codecs.o \ + Python/deepfreeze/encodings.o \ + Python/deepfreeze/encodings.aliases.o \ + Python/deepfreeze/encodings.ascii.o \ + Python/deepfreeze/encodings.utf_8.o \ Python/deepfreeze/io.o \ Python/deepfreeze/_collections_abc.o \ Python/deepfreeze/_sitebuiltins.o \ @@ -1008,6 +1012,18 @@ Python/deepfreeze/abc.c: Python/frozen_modules/abc.h $(DEEPFREEZE_DEPS) Python/deepfreeze/codecs.c: Python/frozen_modules/codecs.h $(DEEPFREEZE_DEPS) $(PYTHON_FOR_FREEZE) $(srcdir)/Tools/scripts/deepfreeze.py Python/frozen_modules/codecs.h -m codecs -o Python/deepfreeze/codecs.c +Python/deepfreeze/encodings.c: Python/frozen_modules/encodings.h $(DEEPFREEZE_DEPS) + $(PYTHON_FOR_FREEZE) $(srcdir)/Tools/scripts/deepfreeze.py Python/frozen_modules/encodings.h -m encodings -o Python/deepfreeze/encodings.c + +Python/deepfreeze/encodings.aliases.c: Python/frozen_modules/encodings.aliases.h $(DEEPFREEZE_DEPS) + $(PYTHON_FOR_FREEZE) $(srcdir)/Tools/scripts/deepfreeze.py Python/frozen_modules/encodings.aliases.h -m encodings.aliases -o Python/deepfreeze/encodings.aliases.c + +Python/deepfreeze/encodings.ascii.c: Python/frozen_modules/encodings.ascii.h $(DEEPFREEZE_DEPS) + $(PYTHON_FOR_FREEZE) $(srcdir)/Tools/scripts/deepfreeze.py Python/frozen_modules/encodings.ascii.h -m encodings.ascii -o Python/deepfreeze/encodings.ascii.c + +Python/deepfreeze/encodings.utf_8.c: Python/frozen_modules/encodings.utf_8.h $(DEEPFREEZE_DEPS) + $(PYTHON_FOR_FREEZE) $(srcdir)/Tools/scripts/deepfreeze.py Python/frozen_modules/encodings.utf_8.h -m encodings.utf_8 -o Python/deepfreeze/encodings.utf_8.c + Python/deepfreeze/io.c: Python/frozen_modules/io.h $(DEEPFREEZE_DEPS) $(PYTHON_FOR_FREEZE) $(srcdir)/Tools/scripts/deepfreeze.py Python/frozen_modules/io.h -m io -o Python/deepfreeze/io.c @@ -1098,6 +1114,10 @@ FROZEN_FILES_IN = \ Lib/zipimport.py \ Lib/abc.py \ Lib/codecs.py \ + Lib/encodings/__init__.py \ + Lib/encodings/aliases.py \ + Lib/encodings/ascii.py \ + Lib/encodings/utf_8.py \ Lib/io.py \ Lib/_collections_abc.py \ Lib/_sitebuiltins.py \ @@ -1123,6 +1143,10 @@ FROZEN_FILES_OUT = \ Python/frozen_modules/zipimport.h \ Python/frozen_modules/abc.h \ Python/frozen_modules/codecs.h \ + Python/frozen_modules/encodings.h \ + Python/frozen_modules/encodings.aliases.h \ + Python/frozen_modules/encodings.ascii.h \ + Python/frozen_modules/encodings.utf_8.h \ Python/frozen_modules/io.h \ Python/frozen_modules/_collections_abc.h \ Python/frozen_modules/_sitebuiltins.h \ @@ -1171,6 +1195,18 @@ Python/frozen_modules/abc.h: Lib/abc.py $(FREEZE_MODULE_DEPS) Python/frozen_modules/codecs.h: Lib/codecs.py $(FREEZE_MODULE_DEPS) $(FREEZE_MODULE) codecs $(srcdir)/Lib/codecs.py Python/frozen_modules/codecs.h +Python/frozen_modules/encodings.h: Lib/encodings/__init__.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) encodings $(srcdir)/Lib/encodings/__init__.py Python/frozen_modules/encodings.h + +Python/frozen_modules/encodings.aliases.h: Lib/encodings/aliases.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) encodings.aliases $(srcdir)/Lib/encodings/aliases.py Python/frozen_modules/encodings.aliases.h + +Python/frozen_modules/encodings.ascii.h: Lib/encodings/ascii.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) encodings.ascii $(srcdir)/Lib/encodings/ascii.py Python/frozen_modules/encodings.ascii.h + +Python/frozen_modules/encodings.utf_8.h: Lib/encodings/utf_8.py $(FREEZE_MODULE_DEPS) + $(FREEZE_MODULE) encodings.utf_8 $(srcdir)/Lib/encodings/utf_8.py Python/frozen_modules/encodings.utf_8.h + Python/frozen_modules/io.h: Lib/io.py $(FREEZE_MODULE_DEPS) $(FREEZE_MODULE) io $(srcdir)/Lib/io.py Python/frozen_modules/io.h diff --git a/Misc/NEWS.d/next/Build/2021-12-10-16-06-13.bpo-45653.FQo2rA.rst b/Misc/NEWS.d/next/Build/2021-12-10-16-06-13.bpo-45653.FQo2rA.rst new file mode 100644 index 00000000000000..fd9f7bd7561244 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2021-12-10-16-06-13.bpo-45653.FQo2rA.rst @@ -0,0 +1 @@ +Parts of the :mod:`encodings` package is now frozen. diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj index 59519cade26705..cbef85283bfaf9 100644 --- a/PCbuild/_freeze_module.vcxproj +++ b/PCbuild/_freeze_module.vcxproj @@ -272,6 +272,34 @@ $(IntDir)codecs.g.c $(PySourcePath)Python\deepfreeze\df.codecs.c + + encodings + $(IntDir)encodings.g.h + $(PySourcePath)Python\frozen_modules\encodings.h + $(IntDir)encodings.g.c + $(PySourcePath)Python\deepfreeze\df.encodings.c + + + encodings.aliases + $(IntDir)encodings.aliases.g.h + $(PySourcePath)Python\frozen_modules\encodings.aliases.h + $(IntDir)encodings.aliases.g.c + $(PySourcePath)Python\deepfreeze\df.encodings.aliases.c + + + encodings.ascii + $(IntDir)encodings.ascii.g.h + $(PySourcePath)Python\frozen_modules\encodings.ascii.h + $(IntDir)encodings.ascii.g.c + $(PySourcePath)Python\deepfreeze\df.encodings.ascii.c + + + encodings.utf_8 + $(IntDir)encodings.utf_8.g.h + $(PySourcePath)Python\frozen_modules\encodings.utf_8.h + $(IntDir)encodings.utf_8.g.c + $(PySourcePath)Python\deepfreeze\df.encodings.utf_8.c + io $(IntDir)io.g.h diff --git a/PCbuild/_freeze_module.vcxproj.filters b/PCbuild/_freeze_module.vcxproj.filters index d107849c856213..2026355ce522b2 100644 --- a/PCbuild/_freeze_module.vcxproj.filters +++ b/PCbuild/_freeze_module.vcxproj.filters @@ -420,6 +420,18 @@ Python Files + + Python Files + + + Python Files + + + Python Files + + + Python Files + Python Files diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 83ae2f08749aa8..767d0806204191 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -532,6 +532,10 @@ + + + + diff --git a/Python/codecs.c b/Python/codecs.c index 343b6e2d03396e..172bc98214b857 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -13,6 +13,7 @@ Copyright (c) Corporation for National Research Initiatives. #include "pycore_interp.h" // PyInterpreterState.codec_search_path #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI +#include "pycore_fileutils.h" // _Py_join_relfile() #include const char *Py_hexdigits = "0123456789abcdef"; @@ -1405,6 +1406,50 @@ static PyObject *surrogateescape_errors(PyObject *self, PyObject *exc) return PyCodec_SurrogateEscapeErrors(exc); } +/* Set encodings.__path__ for frozen encodings package + * + * The encodings package is frozen but most encodings modules are not. The + * __path__ attribute of the encodings package must be reset so importlib is + * able to find the pure Python modules. + * Returns -1 on error, 0 on nothing to do, and 1 on update. + */ +static int +_set_encodings_path(PyObject *mod) { + const PyConfig *config = _Py_GetConfig(); + if (config->stdlib_dir == NULL) { + // no stdlib dir, do nothing + return 0; + } + // os.path.join(stdlib_dir, "encodings") + wchar_t *encodings_dirw = _Py_join_relfile( + config->stdlib_dir, L"encodings"); + if (encodings_dirw == NULL) { + PyErr_NoMemory(); + return -1; + } + PyObject *encodings_dir = PyUnicode_FromWideChar(encodings_dirw, -1); + PyMem_RawFree(encodings_dirw); + if (encodings_dir == NULL) { + return -1; + } + // new __path__ list. The old may contain invalid path from freezing. + PyObject *path = PyList_New(1); + if (path == NULL) { + Py_DECREF(encodings_dir); + return -1; + } + if (PyList_SetItem(path, 0, encodings_dir) < 0) { + return -1; + } + // set and override __path__ + if (PyObject_SetAttrString(mod, "__path__", path) < 0) { + Py_DECREF(path); + return -1; + } + Py_DECREF(path); + return 1; +} + static int _PyCodecRegistry_Init(void) { static struct { @@ -1531,6 +1576,11 @@ static int _PyCodecRegistry_Init(void) if (mod == NULL) { return -1; } + + if (_set_encodings_path(mod) < 0) { + Py_DECREF(mod); + return -1; + } Py_DECREF(mod); interp->codecs_initialized = 1; return 0; diff --git a/Python/frozen.c b/Python/frozen.c index 25cf0a8d37c789..4f139361f1d355 100644 --- a/Python/frozen.c +++ b/Python/frozen.c @@ -44,6 +44,10 @@ #include "frozen_modules/zipimport.h" #include "frozen_modules/abc.h" #include "frozen_modules/codecs.h" +#include "frozen_modules/encodings.h" +#include "frozen_modules/encodings.aliases.h" +#include "frozen_modules/encodings.ascii.h" +#include "frozen_modules/encodings.utf_8.h" #include "frozen_modules/io.h" #include "frozen_modules/_collections_abc.h" #include "frozen_modules/_sitebuiltins.h" @@ -72,6 +76,10 @@ extern PyObject *_Py_get_importlib__bootstrap_external_toplevel(void); extern PyObject *_Py_get_zipimport_toplevel(void); extern PyObject *_Py_get_abc_toplevel(void); extern PyObject *_Py_get_codecs_toplevel(void); +extern PyObject *_Py_get_encodings_toplevel(void); +extern PyObject *_Py_get_encodings_aliases_toplevel(void); +extern PyObject *_Py_get_encodings_ascii_toplevel(void); +extern PyObject *_Py_get_encodings_utf_8_toplevel(void); extern PyObject *_Py_get_io_toplevel(void); extern PyObject *_Py_get__collections_abc_toplevel(void); extern PyObject *_Py_get__sitebuiltins_toplevel(void); @@ -110,6 +118,10 @@ static const struct _frozen stdlib_modules[] = { /* stdlib - startup, without site (python -S) */ {"abc", _Py_M__abc, (int)sizeof(_Py_M__abc), GET_CODE(abc)}, {"codecs", _Py_M__codecs, (int)sizeof(_Py_M__codecs), GET_CODE(codecs)}, + {"encodings", _Py_M__encodings, -(int)sizeof(_Py_M__encodings), GET_CODE(encodings)}, + {"encodings.aliases", _Py_M__encodings_aliases, (int)sizeof(_Py_M__encodings_aliases), GET_CODE(encodings_aliases)}, + {"encodings.ascii", _Py_M__encodings_ascii, (int)sizeof(_Py_M__encodings_ascii), GET_CODE(encodings_ascii)}, + {"encodings.utf_8", _Py_M__encodings_utf_8, (int)sizeof(_Py_M__encodings_utf_8), GET_CODE(encodings_utf_8)}, {"io", _Py_M__io, (int)sizeof(_Py_M__io), GET_CODE(io)}, /* stdlib - startup, with site */ diff --git a/Tools/scripts/freeze_modules.py b/Tools/scripts/freeze_modules.py index cbe8bf1ce60cdc..d27398acc109eb 100644 --- a/Tools/scripts/freeze_modules.py +++ b/Tools/scripts/freeze_modules.py @@ -49,10 +49,10 @@ ('stdlib - startup, without site (python -S)', [ 'abc', 'codecs', - # For now we do not freeze the encodings, due # to the noise all - # those extra modules add to the text printed during the build. - # (See https://github.com/python/cpython/pull/28398#pullrequestreview-756856469.) - #'', + '', # encodings.__init__ + 'encodings.aliases', + 'encodings.ascii', + 'encodings.utf_8', 'io', ]), ('stdlib - startup, with site', [ From 6b2ad71c67ed8fd9fdc9f111cb1e5525861cae4d Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Fri, 10 Dec 2021 17:00:35 +0100 Subject: [PATCH 2/5] Also search in modules_search_paths --- Python/codecs.c | 87 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 28 deletions(-) diff --git a/Python/codecs.c b/Python/codecs.c index 172bc98214b857..cc671788e8a982 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -1411,43 +1411,74 @@ static PyObject *surrogateescape_errors(PyObject *self, PyObject *exc) * The encodings package is frozen but most encodings modules are not. The * __path__ attribute of the encodings package must be reset so importlib is * able to find the pure Python modules. - * Returns -1 on error, 0 on nothing to do, and 1 on update. + * Returns -1 on error */ static int _set_encodings_path(PyObject *mod) { - const PyConfig *config = _Py_GetConfig(); - if (config->stdlib_dir == NULL) { - // no stdlib dir, do nothing - return 0; - } - // os.path.join(stdlib_dir, "encodings") - wchar_t *encodings_dirw = _Py_join_relfile( - config->stdlib_dir, L"encodings"); - if (encodings_dirw == NULL) { - PyErr_NoMemory(); - return -1; - } - PyObject *encodings_dir = PyUnicode_FromWideChar(encodings_dirw, -1); - PyMem_RawFree(encodings_dirw); - if (encodings_dir == NULL) { - return -1; - } - // new __path__ list. The old may contain invalid path from freezing. - PyObject *path = PyList_New(1); + int rc = -1; + PyObject *path = PyList_New(0); if (path == NULL) { - Py_DECREF(encodings_dir); - return -1; + goto exit; } - if (PyList_SetItem(path, 0, encodings_dir) < 0) { - return -1; + const PyConfig *config = _Py_GetConfig(); + /* standard stdlib dir */ + if (config->stdlib_dir != NULL) { + // os.path.join(stdlib_dir, "encodings") + wchar_t *encodings_dirw = _Py_join_relfile( + config->stdlib_dir, L"encodings"); + if (encodings_dirw == NULL) { + PyErr_NoMemory(); + goto exit; + } + PyObject *encodings_dir = PyUnicode_FromWideChar(encodings_dirw, -1); + PyMem_RawFree(encodings_dirw); + if (encodings_dir == NULL) { + goto exit; + } + if (PyList_Append(path, encodings_dir) < 0) { + goto exit; + } + } + // Additional search paths, required for embedding + if (config->module_search_paths_set) { + for (Py_ssize_t i = 0; i < config->module_search_paths.length; ++i) { + wchar_t *encodings_dirw = _Py_join_relfile( + config->module_search_paths.items[i], L"encodings"); + if (encodings_dirw == NULL) { + PyErr_NoMemory(); + goto exit; + } +#ifdef MS_WINDOWS + DWORD attr = GetFileAttributesW(path); + int isdir = (attr != INVALID_FILE_ATTRIBUTES) && + (attr & FILE_ATTRIBUTE_DIRECTORY); +#else + struct stat st; + int isdir = (_Py_wstat(path, &st) == 0) && S_ISDIR(st.st_mode); +#endif + if (!isdir) { + PyMem_RawFree(encodings_dirw); + continue; + } + PyObject *encodings_dir = PyUnicode_FromWideChar(encodings_dirw, -1); + PyMem_RawFree(encodings_dirw); + if (encodings_dir == NULL) { + goto exit; + } + if (PyList_Append(path, encodings_dir) < 0) { + goto exit; + } + } } // set and override __path__ if (PyObject_SetAttrString(mod, "__path__", path) < 0) { - Py_DECREF(path); - return -1; + goto exit; } - Py_DECREF(path); - return 1; + rc = 0; + exit: + Py_XDECREF(path); + + return rc; } static int _PyCodecRegistry_Init(void) From 521b51891fa0eccfd50e3190f99b1c3f2a47b6ea Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Fri, 10 Dec 2021 17:07:17 +0100 Subject: [PATCH 3/5] Pass correct type to stat --- Python/codecs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Python/codecs.c b/Python/codecs.c index cc671788e8a982..e699263cfc13f9 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -1449,12 +1449,12 @@ _set_encodings_path(PyObject *mod) { goto exit; } #ifdef MS_WINDOWS - DWORD attr = GetFileAttributesW(path); + DWORD attr = GetFileAttributesW(encodings_dirw); int isdir = (attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY); #else struct stat st; - int isdir = (_Py_wstat(path, &st) == 0) && S_ISDIR(st.st_mode); + int isdir = (_Py_wstat(encodings_dirw, &st) == 0) && S_ISDIR(st.st_mode); #endif if (!isdir) { PyMem_RawFree(encodings_dirw); From 3cc569499776e03a5c7222635b45dad733ec2765 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Fri, 10 Dec 2021 19:14:54 +0100 Subject: [PATCH 4/5] Fall back to module_search_paths when stdlib_dir is NULL --- Python/codecs.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Python/codecs.c b/Python/codecs.c index e699263cfc13f9..51bc13a6ac6ee8 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -1421,8 +1421,9 @@ _set_encodings_path(PyObject *mod) { goto exit; } const PyConfig *config = _Py_GetConfig(); - /* standard stdlib dir */ if (config->stdlib_dir != NULL) { + // standard library directory + // os.path.join(stdlib_dir, "encodings") wchar_t *encodings_dirw = _Py_join_relfile( config->stdlib_dir, L"encodings"); @@ -1438,9 +1439,8 @@ _set_encodings_path(PyObject *mod) { if (PyList_Append(path, encodings_dir) < 0) { goto exit; } - } - // Additional search paths, required for embedding - if (config->module_search_paths_set) { + } else if (config->module_search_paths_set) { + // No stdlib_dir, search module_search paths for (Py_ssize_t i = 0; i < config->module_search_paths.length; ++i) { wchar_t *encodings_dirw = _Py_join_relfile( config->module_search_paths.items[i], L"encodings"); @@ -1470,14 +1470,15 @@ _set_encodings_path(PyObject *mod) { } } } - // set and override __path__ - if (PyObject_SetAttrString(mod, "__path__", path) < 0) { - goto exit; + if (PyObject_IsTrue(path)) { + // set and override __path__ + if (PyObject_SetAttrString(mod, "__path__", path) < 0) { + goto exit; + } } rc = 0; exit: Py_XDECREF(path); - return rc; } From eef175c20c61d5df78cbf98296805bee8afc425c Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Sat, 11 Dec 2021 10:46:23 +0100 Subject: [PATCH 5/5] use sys._stdlib_dir --- Python/codecs.c | 94 ++++++++++++++++++++----------------------------- 1 file changed, 39 insertions(+), 55 deletions(-) diff --git a/Python/codecs.c b/Python/codecs.c index 51bc13a6ac6ee8..d2f0e6bbd81458 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -1416,69 +1416,53 @@ static PyObject *surrogateescape_errors(PyObject *self, PyObject *exc) static int _set_encodings_path(PyObject *mod) { int rc = -1; - PyObject *path = PyList_New(0); - if (path == NULL) { + PyObject *path = NULL; + PyObject *encodings_dir = NULL; + + // borrowed ref + PyObject *stdlib_dir = PySys_GetObject("_stdlib_dir"); + if (stdlib_dir == NULL) { + rc = 0; goto exit; } - const PyConfig *config = _Py_GetConfig(); - if (config->stdlib_dir != NULL) { - // standard library directory - // os.path.join(stdlib_dir, "encodings") - wchar_t *encodings_dirw = _Py_join_relfile( - config->stdlib_dir, L"encodings"); - if (encodings_dirw == NULL) { - PyErr_NoMemory(); - goto exit; - } - PyObject *encodings_dir = PyUnicode_FromWideChar(encodings_dirw, -1); - PyMem_RawFree(encodings_dirw); - if (encodings_dir == NULL) { - goto exit; - } - if (PyList_Append(path, encodings_dir) < 0) { - goto exit; - } - } else if (config->module_search_paths_set) { - // No stdlib_dir, search module_search paths - for (Py_ssize_t i = 0; i < config->module_search_paths.length; ++i) { - wchar_t *encodings_dirw = _Py_join_relfile( - config->module_search_paths.items[i], L"encodings"); - if (encodings_dirw == NULL) { - PyErr_NoMemory(); - goto exit; - } -#ifdef MS_WINDOWS - DWORD attr = GetFileAttributesW(encodings_dirw); - int isdir = (attr != INVALID_FILE_ATTRIBUTES) && - (attr & FILE_ATTRIBUTE_DIRECTORY); -#else - struct stat st; - int isdir = (_Py_wstat(encodings_dirw, &st) == 0) && S_ISDIR(st.st_mode); -#endif - if (!isdir) { - PyMem_RawFree(encodings_dirw); - continue; - } - PyObject *encodings_dir = PyUnicode_FromWideChar(encodings_dirw, -1); - PyMem_RawFree(encodings_dirw); - if (encodings_dir == NULL) { - goto exit; - } - if (PyList_Append(path, encodings_dir) < 0) { - goto exit; - } - } + Py_ssize_t size; + wchar_t *stdlib_dirw = PyUnicode_AsWideCharString(stdlib_dir, &size); + if (stdlib_dirw == NULL) { + goto exit; } - if (PyObject_IsTrue(path)) { - // set and override __path__ - if (PyObject_SetAttrString(mod, "__path__", path) < 0) { - goto exit; - } + + // encodings_dir = os.path.join(sys._stdlib_dir, "encodings") + wchar_t *encodings_dirw = _Py_join_relfile(stdlib_dirw, L"encodings"); + PyMem_Free((void *)stdlib_dirw); + if (encodings_dirw == NULL) { + PyErr_NoMemory(); + goto exit; + } + + encodings_dir = PyUnicode_FromWideChar(encodings_dirw, -1); + PyMem_RawFree((void *)encodings_dirw); + if (encodings_dir == NULL) { + goto exit; + } + + path = PyList_New(0); + if (path == NULL) { + goto exit; + } + if (PyList_Append(path, encodings_dir) < 0) { + goto exit; } + // encodings.__path__ = [encodings_dir] + if (PyObject_SetAttrString(mod, "__path__", path) < 0) { + goto exit; + } + rc = 0; + exit: Py_XDECREF(path); + Py_XDECREF(encodings_dir); return rc; }