mirror of
https://github.com/python/cpython.git
synced 2026-01-06 23:42:34 +00:00
[3.8] bpo-38234: Fix PyConfig_Read() when Py_SetPath() was called (GH-16298) (GH-16313)
* bpo-38234: Remove _PyPathConfig.dll_path (GH-16307) The DLL path is not computed from any user configuration and cannot be configured by PyConfig. Instead, add a new _Py_dll_path global variable. Remove _PyConfig_SetPathConfig(): replaced with _PyPathConfig_Init(). Py_Initialize() now longer sets the "global path configuration", but only initialize _Py_dll_path. (cherry picked from commitc422167749) * bpo-38234: Fix PyConfig_Read() when Py_SetPath() was called (GH-16298) * If Py_SetPath() has been called, _PyConfig_InitPathConfig() now uses its value. * Py_Initialize() now longer copies path configuration from PyConfig to the global path configuration (_Py_path_config). (cherry picked from commite267793aa4)
This commit is contained in:
parent
245d439320
commit
9f3dcf802e
7 changed files with 110 additions and 104 deletions
|
|
@ -15,6 +15,9 @@ extern "C" {
|
|||
|
||||
|
||||
_PyPathConfig _Py_path_config = _PyPathConfig_INIT;
|
||||
#ifdef MS_WINDOWS
|
||||
wchar_t *_Py_dll_path = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
static int
|
||||
|
|
@ -51,9 +54,6 @@ pathconfig_clear(_PyPathConfig *config)
|
|||
CLEAR(config->prefix);
|
||||
CLEAR(config->program_full_path);
|
||||
CLEAR(config->exec_prefix);
|
||||
#ifdef MS_WINDOWS
|
||||
CLEAR(config->dll_path);
|
||||
#endif
|
||||
CLEAR(config->module_search_path);
|
||||
CLEAR(config->home);
|
||||
CLEAR(config->program_name);
|
||||
|
|
@ -74,6 +74,13 @@ pathconfig_calculate(_PyPathConfig *pathconfig, const PyConfig *config)
|
|||
PyMemAllocatorEx old_alloc;
|
||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
|
||||
if (copy_wstr(&new_config.module_search_path,
|
||||
_Py_path_config.module_search_path) < 0)
|
||||
{
|
||||
status = _PyStatus_NO_MEMORY();
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Calculate program_full_path, prefix, exec_prefix,
|
||||
dll_path (Windows), and module_search_path */
|
||||
status = _PyPathConfig_Calculate(&new_config, config);
|
||||
|
|
@ -114,47 +121,6 @@ pathconfig_calculate(_PyPathConfig *pathconfig, const PyConfig *config)
|
|||
}
|
||||
|
||||
|
||||
PyStatus
|
||||
_PyPathConfig_SetGlobal(const _PyPathConfig *config)
|
||||
{
|
||||
PyStatus status;
|
||||
_PyPathConfig new_config = _PyPathConfig_INIT;
|
||||
|
||||
PyMemAllocatorEx old_alloc;
|
||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
|
||||
#define COPY_ATTR(ATTR) \
|
||||
do { \
|
||||
if (copy_wstr(&new_config.ATTR, config->ATTR) < 0) { \
|
||||
pathconfig_clear(&new_config); \
|
||||
status = _PyStatus_NO_MEMORY(); \
|
||||
goto done; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
COPY_ATTR(program_full_path);
|
||||
COPY_ATTR(prefix);
|
||||
COPY_ATTR(exec_prefix);
|
||||
#ifdef MS_WINDOWS
|
||||
COPY_ATTR(dll_path);
|
||||
#endif
|
||||
COPY_ATTR(module_search_path);
|
||||
COPY_ATTR(program_name);
|
||||
COPY_ATTR(home);
|
||||
COPY_ATTR(base_executable);
|
||||
|
||||
pathconfig_clear(&_Py_path_config);
|
||||
/* Steal new_config strings; don't clear new_config */
|
||||
_Py_path_config = new_config;
|
||||
|
||||
status = _PyStatus_OK();
|
||||
|
||||
done:
|
||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_PyPathConfig_ClearGlobal(void)
|
||||
{
|
||||
|
|
@ -162,6 +128,10 @@ _PyPathConfig_ClearGlobal(void)
|
|||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
|
||||
pathconfig_clear(&_Py_path_config);
|
||||
#ifdef MS_WINDOWS
|
||||
PyMem_RawFree(_Py_dll_path);
|
||||
_Py_dll_path = NULL;
|
||||
#endif
|
||||
|
||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
}
|
||||
|
|
@ -200,12 +170,36 @@ _PyWideStringList_Join(const PyWideStringList *list, wchar_t sep)
|
|||
|
||||
/* Set the global path configuration from config. */
|
||||
PyStatus
|
||||
_PyConfig_SetPathConfig(const PyConfig *config)
|
||||
_PyPathConfig_Init(void)
|
||||
{
|
||||
#ifdef MS_WINDOWS
|
||||
if (_Py_dll_path == NULL) {
|
||||
/* Already set: nothing to do */
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
PyMemAllocatorEx old_alloc;
|
||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
|
||||
_Py_dll_path = _Py_GetDLLPath();
|
||||
|
||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
|
||||
if (_Py_dll_path == NULL) {
|
||||
return _PyStatus_NO_MEMORY();
|
||||
}
|
||||
#endif
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
|
||||
static PyStatus
|
||||
pathconfig_global_init_from_config(const PyConfig *config)
|
||||
{
|
||||
PyStatus status;
|
||||
PyMemAllocatorEx old_alloc;
|
||||
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
|
||||
_PyPathConfig pathconfig = _PyPathConfig_INIT;
|
||||
|
||||
pathconfig.module_search_path = _PyWideStringList_Join(&config->module_search_paths, DELIM);
|
||||
|
|
@ -222,12 +216,6 @@ _PyConfig_SetPathConfig(const PyConfig *config)
|
|||
if (copy_wstr(&pathconfig.exec_prefix, config->exec_prefix) < 0) {
|
||||
goto no_memory;
|
||||
}
|
||||
#ifdef MS_WINDOWS
|
||||
pathconfig.dll_path = _Py_GetDLLPath();
|
||||
if (pathconfig.dll_path == NULL) {
|
||||
goto no_memory;
|
||||
}
|
||||
#endif
|
||||
if (copy_wstr(&pathconfig.program_name, config->program_name) < 0) {
|
||||
goto no_memory;
|
||||
}
|
||||
|
|
@ -238,19 +226,18 @@ _PyConfig_SetPathConfig(const PyConfig *config)
|
|||
goto no_memory;
|
||||
}
|
||||
|
||||
status = _PyPathConfig_SetGlobal(&pathconfig);
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
goto done;
|
||||
}
|
||||
pathconfig_clear(&_Py_path_config);
|
||||
/* Steal new_config strings; don't clear new_config */
|
||||
_Py_path_config = pathconfig;
|
||||
|
||||
status = _PyStatus_OK();
|
||||
goto done;
|
||||
|
||||
no_memory:
|
||||
pathconfig_clear(&pathconfig);
|
||||
status = _PyStatus_NO_MEMORY();
|
||||
|
||||
done:
|
||||
pathconfig_clear(&pathconfig);
|
||||
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
|
||||
return status;
|
||||
}
|
||||
|
|
@ -402,12 +389,17 @@ _PyConfig_InitPathConfig(PyConfig *config)
|
|||
static void
|
||||
pathconfig_global_init(void)
|
||||
{
|
||||
/* Initialize _Py_dll_path if needed */
|
||||
PyStatus status = _PyPathConfig_Init();
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
Py_ExitStatusException(status);
|
||||
}
|
||||
|
||||
if (_Py_path_config.module_search_path != NULL) {
|
||||
/* Already initialized */
|
||||
return;
|
||||
}
|
||||
|
||||
PyStatus status;
|
||||
PyConfig config;
|
||||
_PyConfig_InitCompatConfig(&config);
|
||||
|
||||
|
|
@ -416,7 +408,7 @@ pathconfig_global_init(void)
|
|||
goto error;
|
||||
}
|
||||
|
||||
status = _PyConfig_SetPathConfig(&config);
|
||||
status = pathconfig_global_init_from_config(&config);
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -450,10 +442,6 @@ Py_SetPath(const wchar_t *path)
|
|||
alloc_error |= (new_config.prefix == NULL);
|
||||
new_config.exec_prefix = _PyMem_RawWcsdup(L"");
|
||||
alloc_error |= (new_config.exec_prefix == NULL);
|
||||
#ifdef MS_WINDOWS
|
||||
new_config.dll_path = _Py_GetDLLPath();
|
||||
alloc_error |= (new_config.dll_path == NULL);
|
||||
#endif
|
||||
new_config.module_search_path = _PyMem_RawWcsdup(path);
|
||||
alloc_error |= (new_config.module_search_path == NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -472,7 +472,7 @@ pyinit_core_reconfigure(_PyRuntimeState *runtime,
|
|||
config = &interp->config;
|
||||
|
||||
if (config->_install_importlib) {
|
||||
status = _PyConfig_SetPathConfig(config);
|
||||
status = _PyPathConfig_Init();
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
return status;
|
||||
}
|
||||
|
|
@ -623,6 +623,8 @@ pycore_init_builtins(PyInterpreterState *interp)
|
|||
static PyStatus
|
||||
pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod)
|
||||
{
|
||||
const PyConfig *config = &interp->config;
|
||||
|
||||
PyStatus status = _PyImport_Init(interp);
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
return status;
|
||||
|
|
@ -638,15 +640,15 @@ pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod)
|
|||
return _PyStatus_ERR("can't initialize warnings");
|
||||
}
|
||||
|
||||
if (interp->config._install_importlib) {
|
||||
status = _PyConfig_SetPathConfig(&interp->config);
|
||||
if (config->_install_importlib) {
|
||||
status = _PyPathConfig_Init();
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* This call sets up builtin and frozen import support */
|
||||
if (interp->config._install_importlib) {
|
||||
if (config->_install_importlib) {
|
||||
status = init_importlib(interp, sysmod);
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
return status;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue