8000 bpo-35239: _PySys_EndInit() copies module_search_path (GH-10532) · python/cpython@d2be9a5 · GitHub
[go: up one dir, main page]

Skip to content

Commit d2be9a5

Browse files
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. (cherry picked from commit 37cd982) Co-authored-by: Victor Stinner <vstinner@redhat.com>
1 parent 579c417 commit d2be9a5

File tree

Expand file tree

3 files changed

+28
-13
lines changed

3 files changed

+28
-13
lines changed

Lib/test/test_embed.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -301,10 +301,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
301301
}
302302

303303
# main config
304-
UNTESTED_MAIN_CONFIG = (
305-
# FIXME: untested main configuration variables
306-
'module_search_path',
307-
)
308304
COPY_MAIN_CONFIG = (
309305
# Copy core config to main config for expected values
310306
'argv',
@@ -315,7 +311,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
315311
'install_signal_handlers',
316312
'prefix',
317313
'warnoptions',
318-
# xoptions is created from core_config in check_main_config()
314+
# xoptions is created from core_config in check_main_config().
315+
# 'module_search_paths' is copied to 'module_search_path'.
319316
)
320317

321318
# global config
@@ -389,12 +386,10 @@ def check_main_config(self, config):
389386
main_config = config['main_config']
390387

391388
# main config
392-
for key in self.UNTESTED_MAIN_CONFIG:
393-
del main_config[key]
394-
395389
expected_main = {}
396390
for key in self.COPY_MAIN_CONFIG:
397391
expected_main[key] = core_config[key]
392+
expected_main['module_search_path'] = core_config['module_search_paths']
398393
expected_main['xoptions'] = self.main_xoptions(core_config['xoptions'])
399394
self.assertEqual(main_config, expected_main)
400395

Python/pylifecycle.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -967,8 +967,8 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp,
967967
}
968968

969969
/* Initialize warnings. */
970-
if (interp->config.warnoptions != NULL &&
971-
PyList_Size(interp->config.warnoptions) > 0)
970+
PyObject *warnoptions = PySys_GetObject("warnoptions");
971+
if (warnoptions != NULL && PyList_Size(warnoptions) > 0)
972972
{
973973
PyObject *warnings_module = PyImport_ImportModule("warnings");
974974
if (warnings_module == NULL) {

Python/sysmodule.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2464,7 +2464,20 @@ _PySys_EndInit(PyObject *sysdict, _PyMainInterpreterConfig *config)
24642464
assert(config->exec_prefix != NULL);
24652465
assert(config->base_exec_prefix != NULL);
24662466

2467-
SET_SYS_FROM_STRING_BORROW("path", config->module_search_path);
2467+
#define COPY_LIST(KEY, ATTR) \
2468+
do { \
2469+
assert(PyList_Check(config->ATTR)); \
2470+
PyObject *list = PyList_GetSlice(config->ATTR, \
2471+
0, PyList_GET_SIZE(config->ATTR)); \
2472+
if (list == NULL) { \
2473+
return -1; \
2474+
} \
2475+
SET_SYS_FROM_STRING_BORROW(KEY, list); \
2476+
Py_DECREF(list); \
2477+
} while (0)
2478+
2479+
COPY_LIST("path", module_search_path);
2480+
24682481
SET_SYS_FROM_STRING_BORROW("executable", config->executable);
24692482
SET_SYS_FROM_STRING_BORROW("prefix", config->prefix);
24702483
SET_SYS_FROM_STRING_BORROW("base_prefix", config->base_prefix);
@@ -2475,12 +2488,19 @@ _PySys_EndInit(PyObject *sysdict, _PyMainInterpreterConfig *config)
24752488
SET_SYS_FROM_STRING_BORROW("argv", config->argv);
24762489
}
24772490
if (config->warnoptions != NULL) {
2478-
SET_SYS_FROM_STRING_BORROW("warnoptions", config->warnoptions);
2491+
COPY_LIST("warnoptions", warnoptions);
24792492
}
24802493
if (config->xoptions != NULL) {
2481-
SET_SYS_FROM_STRING_BORROW("_xoptions", config->xoptions);
2494+
PyObject *dict = PyDict_Copy(config->xoptions);
2495+
if (dict == NULL) {
2496+
return -1;
2497+
}
2498+
SET_SYS_FROM_STRING_BORROW("_xoptions", dict);
2499+
Py_DECREF(dict);
24822500
}
24832501

2502+
#undef COPY_LIST
2503+
24842504
/* Set flags to their final values */
24852505
SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags());
24862506
/* prevent user from creating new instances */

0 commit comments

Comments
 (0)
0