bpo-45211: Remember the stdlib dir during startup. (gh-28586)

During runtime startup we figure out the stdlib dir but currently throw that information away. This change preserves it and exposes it via PyConfig.stdlib_dir, _Py_GetStdlibDir(), and sys._stdlib_dir.

https://bugs.python.org/issue45211
This commit is contained in:
Eric Snow 2021-09-28 12:18:28 -06:00 committed by GitHub
parent 84975146a7
commit 0c50b8c0b8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 93 additions and 3 deletions

View file

@ -669,6 +669,7 @@ PyConfig_Clear(PyConfig *config)
_PyWideStringList_Clear(&config->xoptions);
_PyWideStringList_Clear(&config->module_search_paths);
config->module_search_paths_set = 0;
CLEAR(config->stdlib_dir);
CLEAR(config->executable);
CLEAR(config->base_executable);
@ -909,6 +910,7 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2)
COPY_WSTRLIST(xoptions);
COPY_WSTRLIST(module_search_paths);
COPY_ATTR(module_search_paths_set);
COPY_WSTR_ATTR(stdlib_dir);
COPY_WSTR_ATTR(executable);
COPY_WSTR_ATTR(base_executable);
@ -1015,6 +1017,7 @@ _PyConfig_AsDict(const PyConfig *config)
SET_ITEM_WSTR(home);
SET_ITEM_INT(module_search_paths_set);
SET_ITEM_WSTRLIST(module_search_paths);
SET_ITEM_WSTR(stdlib_dir);
SET_ITEM_WSTR(executable);
SET_ITEM_WSTR(base_executable);
SET_ITEM_WSTR(prefix);
@ -1318,6 +1321,7 @@ _PyConfig_FromDict(PyConfig *config, PyObject *dict)
// Path configuration output
GET_UINT(module_search_paths_set);
GET_WSTRLIST(module_search_paths);
GET_WSTR_OPT(stdlib_dir);
GET_WSTR_OPT(executable);
GET_WSTR_OPT(base_executable);
GET_WSTR_OPT(prefix);
@ -3094,6 +3098,7 @@ _Py_DumpPathConfig(PyThreadState *tstate)
PySys_WriteStderr(" environment = %i\n", config->use_environment);
PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
PySys_WriteStderr(" import site = %i\n", config->site_import);
DUMP_CONFIG("stdlib dir", stdlib_dir);
#undef DUMP_CONFIG
#define DUMP_SYS(NAME) \

View file

@ -54,6 +54,7 @@ pathconfig_clear(_PyPathConfig *config)
CLEAR(config->program_full_path);
CLEAR(config->prefix);
CLEAR(config->exec_prefix);
CLEAR(config->stdlib_dir);
CLEAR(config->module_search_path);
CLEAR(config->program_name);
CLEAR(config->home);
@ -83,6 +84,7 @@ pathconfig_copy(_PyPathConfig *config, const _PyPathConfig *config2)
COPY_ATTR(prefix);
COPY_ATTR(exec_prefix);
COPY_ATTR(module_search_path);
COPY_ATTR(stdlib_dir);
COPY_ATTR(program_name);
COPY_ATTR(home);
#ifdef MS_WINDOWS
@ -167,6 +169,7 @@ pathconfig_set_from_config(_PyPathConfig *pathconfig, const PyConfig *config)
COPY_CONFIG(program_full_path, executable);
COPY_CONFIG(prefix, prefix);
COPY_CONFIG(exec_prefix, exec_prefix);
COPY_CONFIG(stdlib_dir, stdlib_dir);
COPY_CONFIG(program_name, program_name);
COPY_CONFIG(home, home);
#ifdef MS_WINDOWS
@ -218,6 +221,7 @@ _PyPathConfig_AsDict(void)
SET_ITEM_STR(prefix);
SET_ITEM_STR(exec_prefix);
SET_ITEM_STR(module_search_path);
SET_ITEM_STR(stdlib_dir);
SET_ITEM_STR(program_name);
SET_ITEM_STR(home);
#ifdef MS_WINDOWS
@ -311,6 +315,7 @@ config_init_module_search_paths(PyConfig *config, _PyPathConfig *pathconfig)
- exec_prefix
- module_search_path
- stdlib_dir
- prefix
- program_full_path
@ -401,6 +406,7 @@ config_init_pathconfig(PyConfig *config, int compute_path_config)
COPY_ATTR(program_full_path, executable);
COPY_ATTR(prefix, prefix);
COPY_ATTR(exec_prefix, exec_prefix);
COPY_ATTR(stdlib_dir, stdlib_dir);
#undef COPY_ATTR
@ -486,16 +492,25 @@ Py_SetPath(const wchar_t *path)
PyMem_RawFree(_Py_path_config.prefix);
PyMem_RawFree(_Py_path_config.exec_prefix);
PyMem_RawFree(_Py_path_config.stdlib_dir);
PyMem_RawFree(_Py_path_config.module_search_path);
_Py_path_config.prefix = _PyMem_RawWcsdup(L"");
_Py_path_config.exec_prefix = _PyMem_RawWcsdup(L"");
// XXX Copy this from the new module_search_path?
if (_Py_path_config.home != NULL) {
_Py_path_config.stdlib_dir = _PyMem_RawWcsdup(_Py_path_config.home);
}
else {
_Py_path_config.stdlib_dir = _PyMem_RawWcsdup(L"");
}
_Py_path_config.module_search_path = _PyMem_RawWcsdup(path);
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
if (_Py_path_config.prefix == NULL
|| _Py_path_config.exec_prefix == NULL
|| _Py_path_config.stdlib_dir == NULL
|| _Py_path_config.module_search_path == NULL)
{
path_out_of_memory(__func__);
@ -515,10 +530,13 @@ Py_SetPythonHome(const wchar_t *home)
PyMem_RawFree(_Py_path_config.home);
_Py_path_config.home = _PyMem_RawWcsdup(home);
if (_Py_path_config.home != NULL) {
_Py_path_config.stdlib_dir = _PyMem_RawWcsdup(home);
}
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
if (_Py_path_config.home == NULL) {
if (_Py_path_config.home == NULL || _Py_path_config.stdlib_dir == NULL) {
path_out_of_memory(__func__);
}
}
@ -572,6 +590,17 @@ Py_GetPath(void)
}
wchar_t *
_Py_GetStdlibDir(void)
{
wchar_t *stdlib_dir = _Py_path_config.stdlib_dir;
if (stdlib_dir != NULL && stdlib_dir[0] != L'\0') {
return stdlib_dir;
}
return NULL;
}
wchar_t *
Py_GetPrefix(void)
{

View file

@ -2974,6 +2974,14 @@ _PySys_UpdateConfig(PyThreadState *tstate)
SET_SYS("_xoptions", sys_create_xoptions_dict(config));
const wchar_t *stdlibdir = _Py_GetStdlibDir();
if (stdlibdir != NULL) {
SET_SYS_FROM_WSTR("_stdlib_dir", stdlibdir);
}
else {
PyDict_SetItemString(sysdict, "_stdlib_dir", Py_None);
}
#undef SET_SYS_FROM_WSTR
#undef COPY_LIST
#undef COPY_WSTR