diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 8101e70f9bc..bd0451a43b9 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -82,7 +82,7 @@ class EmbeddingTestsMixin: return out, err def run_repeated_init_and_subinterpreters(self): - out, err = self.run_embedded_interpreter("repeated_init_and_subinterpreters") + out, err = self.run_embedded_interpreter("test_repeated_init_and_subinterpreters") self.assertEqual(err, "") # The output from _testembed looks like this: @@ -172,7 +172,7 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase): def test_forced_io_encoding(self): # Checks forced configuration of embedded interpreter IO streams env = dict(os.environ, PYTHONIOENCODING="utf-8:surrogateescape") - out, err = self.run_embedded_interpreter("forced_io_encoding", env=env) + out, err = self.run_embedded_interpreter("test_forced_io_encoding", env=env) if support.verbose > 1: print() print(out) @@ -218,7 +218,7 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase): is initialized (via Py_Initialize()). """ env = dict(os.environ, PYTHONPATH=os.pathsep.join(sys.path)) - out, err = self.run_embedded_interpreter("pre_initialization_api", env=env) + out, err = self.run_embedded_interpreter("test_pre_initialization_api", env=env) if MS_WINDOWS: expected_path = self.test_exe else: @@ -234,7 +234,7 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase): """ env = dict(os.environ, PYTHONPATH=os.pathsep.join(sys.path)) out, err = self.run_embedded_interpreter( - "pre_initialization_sys_options", env=env) + "test_pre_initialization_sys_options", env=env) expected_output = ( "sys.warnoptions: ['once', 'module', 'default']\n" "sys._xoptions: {'not_an_option': '1', 'also_not_an_option': '2'}\n" @@ -249,7 +249,7 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase): calling PyEval_InitThreads() must not crash. PyGILState_Ensure() must call PyEval_InitThreads() for us in this case. """ - out, err = self.run_embedded_interpreter("bpo20891") + out, err = self.run_embedded_interpreter("test_bpo20891") self.assertEqual(out, '') self.assertEqual(err, '') @@ -258,7 +258,7 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase): bpo-33932: Calling Py_Initialize() twice should do nothing (and not crash!). """ - out, err = self.run_embedded_interpreter("initialize_twice") + out, err = self.run_embedded_interpreter("test_initialize_twice") self.assertEqual(out, '') self.assertEqual(err, '') @@ -266,12 +266,12 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase): """ bpo-34008: Calling Py_Main() after Py_Initialize() must not fail. """ - out, err = self.run_embedded_interpreter("initialize_pymain") + out, err = self.run_embedded_interpreter("test_initialize_pymain") self.assertEqual(out.rstrip(), "Py_Main() after Py_Initialize: sys.argv=['-c', 'arg2']") self.assertEqual(err, '') def test_run_main(self): - out, err = self.run_embedded_interpreter("run_main") + out, err = self.run_embedded_interpreter("test_run_main") self.assertEqual(out.rstrip(), "_Py_RunMain(): sys.argv=['-c', 'arg2']") self.assertEqual(err, '') @@ -632,13 +632,13 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): self.check_global_config(config) def test_init_default_config(self): - self.check_config("init_initialize_config", api=API_COMPAT) + self.check_config("test_init_initialize_config", api=API_COMPAT) def test_preinit_compat_config(self): - self.check_config("preinit_compat_config", api=API_COMPAT) + self.check_config("test_preinit_compat_config", api=API_COMPAT) def test_init_compat_config(self): - self.check_config("init_compat_config", api=API_COMPAT) + self.check_config("test_init_compat_config", api=API_COMPAT) def test_init_global_config(self): preconfig = { @@ -660,7 +660,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'user_site_directory': 0, 'pathconfig_warnings': 0, } - self.check_config("init_global_config", config, preconfig, + self.check_config("test_init_global_config", config, preconfig, api=API_COMPAT) def test_init_from_config(self): @@ -705,7 +705,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'check_hash_pycs_mode': 'always', 'pathconfig_warnings': 0, } - self.check_config("init_from_config", config, preconfig, + self.check_config("test_init_from_config", config, preconfig, api=API_COMPAT) def test_init_env(self): @@ -732,7 +732,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'faulthandler': 1, 'warnoptions': ['EnvVar'], } - self.check_config("init_env", config, preconfig, + self.check_config("test_init_env", config, preconfig, api=API_COMPAT) def test_init_env_dev_mode(self): @@ -740,7 +740,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): config = dict(dev_mode=1, faulthandler=1, warnoptions=['default']) - self.check_config("init_env_dev_mode", config, preconfig, + self.check_config("test_init_env_dev_mode", config, preconfig, api=API_COMPAT) def test_init_env_dev_mode_alloc(self): @@ -748,7 +748,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): config = dict(dev_mode=1, faulthandler=1, warnoptions=['default']) - self.check_config("init_env_dev_mode_alloc", config, preconfig, + self.check_config("test_init_env_dev_mode_alloc", config, preconfig, api=API_COMPAT) def test_init_dev_mode(self): @@ -760,7 +760,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'dev_mode': 1, 'warnoptions': ['default'], } - self.check_config("init_dev_mode", config, preconfig, + self.check_config("test_init_dev_mode", config, preconfig, api=API_PYTHON) def test_preinit_parse_argv(self): @@ -777,7 +777,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'warnoptions': ['default'], 'xoptions': ['dev'], } - self.check_config("preinit_parse_argv", config, preconfig, + self.check_config("test_preinit_parse_argv", config, preconfig, api=API_PYTHON) def test_preinit_dont_parse_argv(self): @@ -790,7 +790,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): "-X", "dev", "-X", "utf8", "script.py"], 'isolated': 0, } - self.check_config("preinit_dont_parse_argv", config, preconfig, + self.check_config("test_preinit_dont_parse_argv", config, preconfig, api=API_ISOLATED) def test_init_isolated_flag(self): @@ -799,7 +799,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("init_isolated_flag", config, api=API_PYTHON) + self.check_config("test_init_isolated_flag", config, api=API_PYTHON) def test_preinit_isolated1(self): # _PyPreConfig.isolated=1, _PyCoreConfig.isolated not set @@ -808,7 +808,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("preinit_isolated1", config, api=API_COMPAT) + self.check_config("test_preinit_isolated1", config, api=API_COMPAT) def test_preinit_isolated2(self): # _PyPreConfig.isolated=0, _PyCoreConfig.isolated=1 @@ -817,16 +817,19 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("preinit_isolated2", config, api=API_COMPAT) + self.check_config("test_preinit_isolated2", config, api=API_COMPAT) def test_preinit_isolated_config(self): - self.check_config("preinit_isolated_config", api=API_ISOLATED) + self.check_config("test_preinit_isolated_config", api=API_ISOLATED) def test_init_isolated_config(self): - self.check_config("init_isolated_config", api=API_ISOLATED) + self.check_config("test_init_isolated_config", api=API_ISOLATED) + + def test_preinit_python_config(self): + self.check_config("test_preinit_python_config", api=API_PYTHON) def test_init_python_config(self): - self.check_config("init_python_config", api=API_PYTHON) + self.check_config("test_init_python_config", api=API_PYTHON) def test_init_dont_configure_locale(self): # _PyPreConfig.configure_locale=0 @@ -834,7 +837,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'configure_locale': 0, 'coerce_c_locale': 0, } - self.check_config("init_dont_configure_locale", {}, preconfig, + self.check_config("test_init_dont_configure_locale", {}, preconfig, api=API_PYTHON) def test_init_read_set(self): @@ -842,7 +845,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'program_name': './init_read_set', 'executable': 'my_executable', } - self.check_config("init_read_set", core_config, + self.check_config("test_init_read_set", core_config, api=API_PYTHON, add_path="init_read_set_path") @@ -855,7 +858,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'run_command': code + '\n', 'parse_argv': 1, } - self.check_config("init_run_main", core_config, api=API_PYTHON) + self.check_config("test_init_run_main", core_config, api=API_PYTHON) def test_init_main(self): code = ('import _testinternalcapi, json; ' @@ -867,7 +870,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'parse_argv': 1, '_init_main': 0, } - self.check_config("init_main", core_config, + self.check_config("test_init_main", core_config, api=API_PYTHON, stderr="Run Python code before _Py_InitializeMain") @@ -879,7 +882,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'run_command': 'pass\n', 'use_environment': 0, } - self.check_config("init_parse_argv", core_config, api=API_PYTHON) + self.check_config("test_init_parse_argv", core_config, api=API_PYTHON) def test_init_dont_parse_argv(self): pre_config = { @@ -890,7 +893,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'argv': ['./argv0', '-E', '-c', 'pass', 'arg1', '-v', 'arg3'], 'program_name': './argv0', } - self.check_config("init_dont_parse_argv", core_config, pre_config, + self.check_config("test_init_dont_parse_argv", core_config, pre_config, api=API_PYTHON) diff --git a/Programs/_testembed.c b/Programs/_testembed.c index a273930e10a..7f8ea07ee3e 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -1243,39 +1243,39 @@ struct TestCase }; static struct TestCase TestCases[] = { - { "forced_io_encoding", test_forced_io_encoding }, - { "repeated_init_and_subinterpreters", test_repeated_init_and_subinterpreters }, - { "pre_initialization_api", test_pre_initialization_api }, - { "pre_initialization_sys_options", test_pre_initialization_sys_options }, - { "bpo20891", test_bpo20891 }, - { "initialize_twice", test_initialize_twice }, - { "initialize_pymain", test_initialize_pymain }, - { "init_initialize_config", test_init_initialize_config }, - { "preinit_compat_config", test_preinit_compat_config }, - { "init_compat_config", test_init_compat_config }, - { "init_global_config", test_init_global_config }, - { "init_from_config", test_init_from_config }, - { "init_parse_argv", test_init_parse_argv }, - { "init_dont_parse_argv", test_init_dont_parse_argv }, - { "init_env", test_init_env }, - { "init_env_dev_mode", test_init_env_dev_mode }, - { "init_env_dev_mode_alloc", test_init_env_dev_mode_alloc }, - { "init_dont_configure_locale", test_init_dont_configure_locale }, - { "init_dev_mode", test_init_dev_mode }, - { "init_isolated_flag", test_init_isolated_flag }, - { "preinit_isolated_config", test_preinit_isolated_config }, - { "init_isolated_config", test_init_isolated_config }, - { "preinit_python_config", test_preinit_python_config }, - { "init_python_config", test_init_python_config }, - { "preinit_isolated1", test_preinit_isolated1 }, - { "preinit_isolated2", test_preinit_isolated2 }, - { "preinit_parse_argv", test_preinit_parse_argv }, - { "preinit_dont_parse_argv", test_preinit_dont_parse_argv }, - { "init_read_set", test_init_read_set }, - { "init_run_main", test_init_run_main }, - { "init_main", test_init_main }, - { "run_main", test_run_main }, - { NULL, NULL } + {"test_forced_io_encoding", test_forced_io_encoding}, + {"test_repeated_init_and_subinterpreters", test_repeated_init_and_subinterpreters}, + {"test_pre_initialization_api", test_pre_initialization_api}, + {"test_pre_initialization_sys_options", test_pre_initialization_sys_options}, + {"test_bpo20891", test_bpo20891}, + {"test_initialize_twice", test_initialize_twice}, + {"test_initialize_pymain", test_initialize_pymain}, + {"test_init_initialize_config", test_init_initialize_config}, + {"test_preinit_compat_config", test_preinit_compat_config}, + {"test_init_compat_config", test_init_compat_config}, + {"test_init_global_config", test_init_global_config}, + {"test_init_from_config", test_init_from_config}, + {"test_init_parse_argv", test_init_parse_argv}, + {"test_init_dont_parse_argv", test_init_dont_parse_argv}, + {"test_init_env", test_init_env}, + {"test_init_env_dev_mode", test_init_env_dev_mode}, + {"test_init_env_dev_mode_alloc", test_init_env_dev_mode_alloc}, + {"test_init_dont_configure_locale", test_init_dont_configure_locale}, + {"test_init_dev_mode", test_init_dev_mode}, + {"test_init_isolated_flag", test_init_isolated_flag}, + {"test_preinit_isolated_config", test_preinit_isolated_config}, + {"test_init_isolated_config", test_init_isolated_config}, + {"test_preinit_python_config", test_preinit_python_config}, + {"test_init_python_config", test_init_python_config}, + {"test_preinit_isolated1", test_preinit_isolated1}, + {"test_preinit_isolated2", test_preinit_isolated2}, + {"test_preinit_parse_argv", test_preinit_parse_argv}, + {"test_preinit_dont_parse_argv", test_preinit_dont_parse_argv}, + {"test_init_read_set", test_init_read_set}, + {"test_init_run_main", test_init_run_main}, + {"test_init_main", test_init_main}, + {"test_run_main", test_run_main}, + {NULL, NULL} }; int main(int argc, char *argv[]) diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 21c386bb4a3..1084def9ce0 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -447,9 +447,9 @@ _Py_SetLocaleFromEnv(int category) */ static _PyInitError -_Py_Initialize_ReconfigureCore(_PyRuntimeState *runtime, - PyInterpreterState **interp_p, - const _PyCoreConfig *core_config) +pyinit_core_reconfigure(_PyRuntimeState *runtime, + PyInterpreterState **interp_p, + const _PyCoreConfig *core_config) { _PyInitError err; PyThreadState *tstate = _PyThreadState_GET(); @@ -657,9 +657,9 @@ pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod) static _PyInitError -_Py_InitializeCore_impl(_PyRuntimeState *runtime, - PyInterpreterState **interp_p, - const _PyCoreConfig *core_config) +pyinit_core_config(_PyRuntimeState *runtime, + PyInterpreterState **interp_p, + const _PyCoreConfig *core_config) { PyInterpreterState *interp; @@ -801,41 +801,6 @@ _Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig, } -static _PyInitError -pyinit_coreconfig(_PyRuntimeState *runtime, - _PyCoreConfig *config, - const _PyCoreConfig *src_config, - const _PyArgv *args, - PyInterpreterState **interp_p) -{ - assert(src_config != NULL); - - _PyInitError err = _PyCoreConfig_Copy(config, src_config); - if (_Py_INIT_FAILED(err)) { - return err; - } - - if (args) { - err = _PyCoreConfig_SetPyArgv(config, args); - if (_Py_INIT_FAILED(err)) { - return err; - } - } - - err = _PyCoreConfig_Read(config); - if (_Py_INIT_FAILED(err)) { - return err; - } - - if (!runtime->core_initialized) { - return _Py_InitializeCore_impl(runtime, interp_p, config); - } - else { - return _Py_Initialize_ReconfigureCore(runtime, interp_p, config); - } -} - - /* Begin interpreter initialization * * On return, the first thread and interpreter state have been created, @@ -854,10 +819,10 @@ pyinit_coreconfig(_PyRuntimeState *runtime, * safe to call without calling Py_Initialize first) */ static _PyInitError -_Py_InitializeCore(_PyRuntimeState *runtime, - const _PyCoreConfig *src_config, - const _PyArgv *args, - PyInterpreterState **interp_p) +pyinit_core(_PyRuntimeState *runtime, + const _PyCoreConfig *src_config, + const _PyArgv *args, + PyInterpreterState **interp_p) { _PyInitError err; @@ -866,10 +831,38 @@ _Py_InitializeCore(_PyRuntimeState *runtime, return err; } - _PyCoreConfig local_config; - _PyCoreConfig_InitCompatConfig(&local_config); - err = pyinit_coreconfig(runtime, &local_config, src_config, args, interp_p); - _PyCoreConfig_Clear(&local_config); + _PyCoreConfig config; + _PyCoreConfig_InitCompatConfig(&config); + + err = _PyCoreConfig_Copy(&config, src_config); + if (_Py_INIT_FAILED(err)) { + goto done; + } + + if (args) { + err = _PyCoreConfig_SetPyArgv(&config, args); + if (_Py_INIT_FAILED(err)) { + goto done; + } + } + + err = _PyCoreConfig_Read(&config); + if (_Py_INIT_FAILED(err)) { + goto done; + } + + if (!runtime->core_initialized) { + err = pyinit_core_config(runtime, interp_p, &config); + } + else { + err = pyinit_core_reconfigure(runtime, interp_p, &config); + } + if (_Py_INIT_FAILED(err)) { + goto done; + } + +done: + _PyCoreConfig_Clear(&config); return err; } @@ -907,8 +900,7 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp) * non-zero return code. */ static _PyInitError -_Py_InitializeMainInterpreter(_PyRuntimeState *runtime, - PyInterpreterState *interp) +pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) { if (!runtime->core_initialized) { return _Py_INIT_ERR("runtime core not initialized"); @@ -1015,14 +1007,14 @@ _Py_InitializeMain(void) _PyRuntimeState *runtime = &_PyRuntime; PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; - return _Py_InitializeMainInterpreter(runtime, interp); + return pyinit_main(runtime, interp); } #undef _INIT_DEBUG_PRINT static _PyInitError -init_python(const _PyCoreConfig *config, const _PyArgv *args) +pyinit_python(const _PyCoreConfig *config, const _PyArgv *args) { if (config == NULL) { return _Py_INIT_ERR("initialization config is NULL"); @@ -1037,14 +1029,14 @@ init_python(const _PyCoreConfig *config, const _PyArgv *args) _PyRuntimeState *runtime = &_PyRuntime; PyInterpreterState *interp = NULL; - err = _Py_InitializeCore(runtime, config, args, &interp); + err = pyinit_core(runtime, config, args, &interp); if (_Py_INIT_FAILED(err)) { return err; } config = &interp->core_config; if (config->_init_main) { - err = _Py_InitializeMainInterpreter(runtime, interp); + err = pyinit_main(runtime, interp); if (_Py_INIT_FAILED(err)) { return err; } @@ -1059,7 +1051,7 @@ _Py_InitializeFromArgs(const _PyCoreConfig *config, Py_ssize_t argc, char * const *argv) { _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv}; - return init_python(config, &args); + return pyinit_python(config, &args); } @@ -1068,14 +1060,14 @@ _Py_InitializeFromWideArgs(const _PyCoreConfig *config, Py_ssize_t argc, wchar_t * const *argv) { _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv}; - return init_python(config, &args); + return pyinit_python(config, &args); } _PyInitError _Py_InitializeFromConfig(const _PyCoreConfig *config) { - return init_python(config, NULL); + return pyinit_python(config, NULL); }