bpo-35239: _PySys_EndInit() copies module_search_path (GH-10532)
* The _PySys_EndInit() function now copies the config->module_search_path list, so config is longer modified when sys.path is updated. * config->warnoptions list and config->xoptions dict are also copied * test_embed: InitConfigTests now also tests main_config['module_search_path'] * Fix _Py_InitializeMainInterpreter(): don't use config->warnoptions but sys.warnoptions to decide if the warnings module should be imported at startup.
This commit is contained in:
parent
b65413b497
commit
37cd982df0
|
@ -331,10 +331,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
})
|
})
|
||||||
|
|
||||||
# main config
|
# main config
|
||||||
UNTESTED_MAIN_CONFIG = (
|
|
||||||
# FIXME: untested main configuration variables
|
|
||||||
'module_search_path',
|
|
||||||
)
|
|
||||||
COPY_MAIN_CONFIG = (
|
COPY_MAIN_CONFIG = (
|
||||||
# Copy core config to main config for expected values
|
# Copy core config to main config for expected values
|
||||||
'argv',
|
'argv',
|
||||||
|
@ -346,7 +342,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
'prefix',
|
'prefix',
|
||||||
'pycache_prefix',
|
'pycache_prefix',
|
||||||
'warnoptions',
|
'warnoptions',
|
||||||
# xoptions is created from core_config in check_main_config()
|
# xoptions is created from core_config in check_main_config().
|
||||||
|
# 'module_search_paths' is copied to 'module_search_path'.
|
||||||
)
|
)
|
||||||
|
|
||||||
# global config
|
# global config
|
||||||
|
@ -426,12 +423,10 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
main_config = config['main_config']
|
main_config = config['main_config']
|
||||||
|
|
||||||
# main config
|
# main config
|
||||||
for key in self.UNTESTED_MAIN_CONFIG:
|
|
||||||
del main_config[key]
|
|
||||||
|
|
||||||
expected_main = {}
|
expected_main = {}
|
||||||
for key in self.COPY_MAIN_CONFIG:
|
for key in self.COPY_MAIN_CONFIG:
|
||||||
expected_main[key] = core_config[key]
|
expected_main[key] = core_config[key]
|
||||||
|
expected_main['module_search_path'] = core_config['module_search_paths']
|
||||||
expected_main['xoptions'] = self.main_xoptions(core_config['xoptions'])
|
expected_main['xoptions'] = self.main_xoptions(core_config['xoptions'])
|
||||||
self.assertEqual(main_config, expected_main)
|
self.assertEqual(main_config, expected_main)
|
||||||
|
|
||||||
|
|
|
@ -836,8 +836,8 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize warnings. */
|
/* Initialize warnings. */
|
||||||
if (interp->config.warnoptions != NULL &&
|
PyObject *warnoptions = PySys_GetObject("warnoptions");
|
||||||
PyList_Size(interp->config.warnoptions) > 0)
|
if (warnoptions != NULL && PyList_Size(warnoptions) > 0)
|
||||||
{
|
{
|
||||||
PyObject *warnings_module = PyImport_ImportModule("warnings");
|
PyObject *warnings_module = PyImport_ImportModule("warnings");
|
||||||
if (warnings_module == NULL) {
|
if (warnings_module == NULL) {
|
||||||
|
|
|
@ -2488,7 +2488,20 @@ _PySys_EndInit(PyObject *sysdict, PyInterpreterState *interp)
|
||||||
assert(config->exec_prefix != NULL);
|
assert(config->exec_prefix != NULL);
|
||||||
assert(config->base_exec_prefix != NULL);
|
assert(config->base_exec_prefix != NULL);
|
||||||
|
|
||||||
SET_SYS_FROM_STRING_BORROW("path", config->module_search_path);
|
#define COPY_LIST(KEY, ATTR) \
|
||||||
|
do { \
|
||||||
|
assert(PyList_Check(config->ATTR)); \
|
||||||
|
PyObject *list = PyList_GetSlice(config->ATTR, \
|
||||||
|
0, PyList_GET_SIZE(config->ATTR)); \
|
||||||
|
if (list == NULL) { \
|
||||||
|
return -1; \
|
||||||
|
} \
|
||||||
|
SET_SYS_FROM_STRING_BORROW(KEY, list); \
|
||||||
|
Py_DECREF(list); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
COPY_LIST("path", module_search_path);
|
||||||
|
|
||||||
SET_SYS_FROM_STRING_BORROW("executable", config->executable);
|
SET_SYS_FROM_STRING_BORROW("executable", config->executable);
|
||||||
SET_SYS_FROM_STRING_BORROW("prefix", config->prefix);
|
SET_SYS_FROM_STRING_BORROW("prefix", config->prefix);
|
||||||
SET_SYS_FROM_STRING_BORROW("base_prefix", config->base_prefix);
|
SET_SYS_FROM_STRING_BORROW("base_prefix", config->base_prefix);
|
||||||
|
@ -2505,12 +2518,19 @@ _PySys_EndInit(PyObject *sysdict, PyInterpreterState *interp)
|
||||||
SET_SYS_FROM_STRING_BORROW("argv", config->argv);
|
SET_SYS_FROM_STRING_BORROW("argv", config->argv);
|
||||||
}
|
}
|
||||||
if (config->warnoptions != NULL) {
|
if (config->warnoptions != NULL) {
|
||||||
SET_SYS_FROM_STRING_BORROW("warnoptions", config->warnoptions);
|
COPY_LIST("warnoptions", warnoptions);
|
||||||
}
|
}
|
||||||
if (config->xoptions != NULL) {
|
if (config->xoptions != NULL) {
|
||||||
SET_SYS_FROM_STRING_BORROW("_xoptions", config->xoptions);
|
PyObject *dict = PyDict_Copy(config->xoptions);
|
||||||
|
if (dict == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
SET_SYS_FROM_STRING_BORROW("_xoptions", dict);
|
||||||
|
Py_DECREF(dict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef COPY_LIST
|
||||||
|
|
||||||
/* Set flags to their final values */
|
/* Set flags to their final values */
|
||||||
SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags());
|
SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags());
|
||||||
/* prevent user from creating new instances */
|
/* prevent user from creating new instances */
|
||||||
|
|
Loading…
Reference in New Issue