diff --git a/Include/coreconfig.h b/Include/coreconfig.h index 0ed3222a15e142..8a73e1e38f59c2 100644 --- a/Include/coreconfig.h +++ b/Include/coreconfig.h @@ -107,13 +107,9 @@ typedef struct { If set to -1 (default), inherit Py_UTF8Mode value. */ int utf8_mode; - wchar_t *pycache_prefix; /* PYTHONPYCACHEPREFIX, -X pycache_prefix=PATH */ - - wchar_t *program_name; /* Program name, see also Py_GetProgramName() */ int argc; /* Number of command line arguments, -1 means unset */ wchar_t **argv; /* Command line arguments */ - wchar_t *program; /* argv[0] or "" */ int nxoption; /* Number of -X options */ wchar_t **xoptions; /* -X options */ @@ -339,15 +335,54 @@ typedef struct { /* Note: _PyCoreConfig_INIT sets other fields to 0/NULL */ +typedef struct { + _PyCoreConfig core_config; + wchar_t *program_name; /* Program name, see also Py_GetProgramName() */ + wchar_t *program; /* argv[0] or "" */ + wchar_t *pycache_prefix; /* PYTHONPYCACHEPREFIX, -X pycache_prefix=PATH */ +} _PyPreConfig; + +#define _PyPreConfig_INIT \ + (_PyPreConfig){.core_config = _PyCoreConfig_INIT} +/* Note: _PyPreConfig_INIT sets other fields to 0/NULL */ + + +typedef struct { + _PyCoreConfig core_config; + PyObject *argv; /* sys.argv list, can be NULL */ + PyObject *program_name; /* Program name, see also Py_GetProgramName() */ + PyObject* program; /* argv[0] or "" */ + PyObject *executable; /* sys.executable str */ + PyObject *prefix; /* sys.prefix str */ + PyObject *base_prefix; /* sys.base_prefix str, can be NULL */ + PyObject *exec_prefix; /* sys.exec_prefix str */ + PyObject *base_exec_prefix; /* sys.base_exec_prefix str, can be NULL */ + PyObject *warnoptions; /* sys.warnoptions list, can be NULL */ + PyObject *xoptions; /* sys._xoptions dict, can be NULL */ + PyObject *module_search_path; /* sys.path list */ + PyObject *pycache_prefix; /* sys.pycache_prefix str, can be NULL */ +} _PyMainInterpreterConfig; + +#define _PyMainInterpreterConfig_INIT \ + (_PyMainInterpreterConfig){ \ + .core_config = _PyCoreConfig_INIT} +/* Note: _PyMainInterpreterConfig_INIT sets other fields to 0/NULL */ + + #ifndef Py_LIMITED_API -PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config); +PyAPI_FUNC(void) _PyPreConfig_Clear(_PyPreConfig *config); +PyAPI_FUNC(int) _PyPreConfig_Copy(_PyPreConfig *config, + const _PyPreConfig *config2); +PyAPI_FUNC(_PyInitError) _PyPreConfig_Read(_PyPreConfig *config); +PyAPI_FUNC(_PyInitError) _PyPreConfig_SetPathConfig( + const _PyPreConfig *config); + PyAPI_FUNC(void) _PyCoreConfig_Clear(_PyCoreConfig *); PyAPI_FUNC(int) _PyCoreConfig_Copy( _PyCoreConfig *config, const _PyCoreConfig *config2); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPathConfig(_PyCoreConfig *config); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPathConfig( - const _PyCoreConfig *config); +PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPathConfig( + _PyPreConfig *preconfig); PyAPI_FUNC(void) _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config); PyAPI_FUNC(void) _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config); PyAPI_FUNC(const char*) _PyCoreConfig_GetEnv( diff --git a/Include/internal/pycore_pathconfig.h b/Include/internal/pycore_pathconfig.h index 267e690976da87..0a78a3d1f03a37 100644 --- a/Include/internal/pycore_pathconfig.h +++ b/Include/internal/pycore_pathconfig.h @@ -58,6 +58,7 @@ PyAPI_FUNC(_PyInitError) _PyPathConfig_SetGlobal( PyAPI_FUNC(_PyInitError) _PyPathConfig_Calculate_impl( _PyPathConfig *config, + const _PyPreConfig *pre_config, const _PyCoreConfig *core_config); PyAPI_FUNC(PyObject*) _PyPathConfig_ComputeArgv0(int argc, wchar_t **argv); PyAPI_FUNC(int) _Py_FindEnvConfigValue( diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h index 7d383aa0899a59..fa243976dbec30 100644 --- a/Include/pylifecycle.h +++ b/Include/pylifecycle.h @@ -23,16 +23,12 @@ PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding, #ifndef Py_LIMITED_API -/* PEP 432 Multi-phase initialization API (Private while provisional!) */ -PyAPI_FUNC(_PyInitError) _Py_InitializeCore( - PyInterpreterState **interp, - const _PyCoreConfig *); PyAPI_FUNC(int) _Py_IsCoreInitialized(void); PyAPI_FUNC(_PyInitError) _PyMainInterpreterConfig_Read( _PyMainInterpreterConfig *config, - const _PyCoreConfig *core_config); + const _PyPreConfig *preconfig); PyAPI_FUNC(void) _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *); PyAPI_FUNC(int) _PyMainInterpreterConfig_Copy( _PyMainInterpreterConfig *config, @@ -51,7 +47,8 @@ PyAPI_FUNC(void) Py_Initialize(void); PyAPI_FUNC(void) Py_InitializeEx(int); #ifndef Py_LIMITED_API PyAPI_FUNC(_PyInitError) _Py_InitializeFromConfig( - const _PyCoreConfig *config); + const _PyPreConfig *config, + PyInterpreterState **interp_p); PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalInitError(_PyInitError err); #endif PyAPI_FUNC(void) Py_Finalize(void); diff --git a/Include/pystate.h b/Include/pystate.h index 58499ea35b4741..24150a90a16597 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -25,28 +25,6 @@ typedef struct _is PyInterpreterState; #else typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int); -/* Placeholders while working on the new configuration API - * - * See PEP 432 for final anticipated contents - */ -typedef struct { - int install_signal_handlers; /* Install signal handlers? -1 means unset */ - PyObject *argv; /* sys.argv list, can be NULL */ - PyObject *executable; /* sys.executable str */ - PyObject *prefix; /* sys.prefix str */ - PyObject *base_prefix; /* sys.base_prefix str, can be NULL */ - PyObject *exec_prefix; /* sys.exec_prefix str */ - PyObject *base_exec_prefix; /* sys.base_exec_prefix str, can be NULL */ - PyObject *warnoptions; /* sys.warnoptions list, can be NULL */ - PyObject *xoptions; /* sys._xoptions dict, can be NULL */ - PyObject *module_search_path; /* sys.path list */ - PyObject *pycache_prefix; /* sys.pycache_prefix str, can be NULL */ -} _PyMainInterpreterConfig; - -#define _PyMainInterpreterConfig_INIT \ - (_PyMainInterpreterConfig){.install_signal_handlers = -1} -/* Note: _PyMainInterpreterConfig_INIT sets other fields to 0/NULL */ - typedef struct _is { struct _is *next; @@ -79,7 +57,6 @@ typedef struct _is { int codecs_initialized; int fscodec_initialized; - _PyCoreConfig core_config; _PyMainInterpreterConfig config; #ifdef HAVE_DLOPEN int dlopenflags; diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 3f383d7fd50c8f..f03c3c40104272 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -288,10 +288,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'coerce_c_locale': 0, 'coerce_c_locale_warn': 0, - 'pycache_prefix': None, - 'program_name': './_testembed', 'argv': [], - 'program': None, 'xoptions': [], 'warnoptions': [], @@ -331,6 +328,11 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): }) # main config + DEFAULT_MAIN_CONFIG = { + 'program_name': './_testembed', + 'program': None, + 'pycache_prefix': None, + } COPY_MAIN_CONFIG = ( # Copy core config to main config for expected values 'argv', @@ -338,9 +340,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'base_prefix', 'exec_prefix', 'executable', - 'install_signal_handlers', 'prefix', - 'pycache_prefix', 'warnoptions', # xoptions is created from core_config in check_main_config(). # 'module_search_paths' is copied to 'module_search_path'. @@ -418,17 +418,20 @@ def main_xoptions(self, xoptions_list): xoptions[opt] = True return xoptions - def check_main_config(self, config): + def check_main_config(self, config, expected=None): core_config = config['core_config'] main_config = config['main_config'] # main config - expected_main = {} + if expected is not None: + expected = dict(self.DEFAULT_MAIN_CONFIG, **expected) + else: + expected = dict(self.DEFAULT_MAIN_CONFIG) for key in self.COPY_MAIN_CONFIG: - 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']) - self.assertEqual(main_config, expected_main) + expected[key] = core_config[key] + expected['module_search_path'] = core_config['module_search_paths'] + expected['xoptions'] = self.main_xoptions(core_config['xoptions']) + self.assertEqual(main_config, expected) def check_core_config(self, config, expected, env): if expected['stdio_encoding'] is None or expected['stdio_errors'] is None: @@ -463,8 +466,8 @@ def check_global_config(self, config): self.assertEqual(config['global_config'], expected_global) - def check_config(self, testname, expected): - expected = dict(self.DEFAULT_CORE_CONFIG, **expected) + def check_config(self, testname, expected_core, expected_main=None): + expected_core = dict(self.DEFAULT_CORE_CONFIG, **expected_core) env = dict(os.environ) # Remove PYTHON* environment variables to get deterministic environment @@ -480,16 +483,15 @@ def check_config(self, testname, expected): # Ignore err config = json.loads(out) - self.check_core_config(config, expected, env) - self.check_main_config(config) + self.check_core_config(config, expected_core, env) + self.check_main_config(config, expected_main) self.check_global_config(config) def test_init_default_config(self): self.check_config("init_default_config", {}) def test_init_global_config(self): - config = { - 'program_name': './globalvar', + core_config = { 'site_import': 0, 'bytes_warning': 1, 'inspect': 1, @@ -508,7 +510,10 @@ def test_init_global_config(self): 'user_site_directory': 0, '_frozen': 1, } - self.check_config("init_global_config", config) + main_config = { + 'program_name': './globalvar', + } + self.check_config("init_global_config", core_config, main_config) def test_init_from_config(self): config = { @@ -528,10 +533,7 @@ def test_init_from_config(self): 'filesystem_encoding': 'utf-8', 'filesystem_errors': self.UTF8_MODE_ERRORS, - 'pycache_prefix': 'conf_pycache_prefix', - 'program_name': './conf_program_name', 'argv': ['-c', 'pass'], - 'program': 'conf_program', 'xoptions': ['core_xoption1=3', 'core_xoption2=', 'core_xoption3'], 'warnoptions': ['default', 'error::ResourceWarning'], @@ -550,10 +552,15 @@ def test_init_from_config(self): '_check_hash_pycs_mode': 'always', '_frozen': 1, } - self.check_config("init_from_config", config) + main_config = { + 'program_name': './conf_program_name', + 'program': 'conf_program', + 'pycache_prefix': 'conf_pycache_prefix', + } + self.check_config("init_from_config", config, main_config) def test_init_env(self): - config = { + core_config = { 'use_hash_seed': 1, 'hash_seed': 42, 'allocator': 'malloc_debug', @@ -565,7 +572,6 @@ def test_init_env(self): 'filesystem_errors': self.UTF8_MODE_ERRORS, 'inspect': 1, 'optimization_level': 2, - 'pycache_prefix': 'env_pycache_prefix', 'write_bytecode': 0, 'verbose': 1, 'buffered_stdio': 0, @@ -575,7 +581,10 @@ def test_init_env(self): 'faulthandler': 1, 'dev_mode': 1, } - self.check_config("init_env", config) + main_config = { + 'pycache_prefix': 'env_pycache_prefix', + } + self.check_config("init_env", core_config, main_config) def test_init_dev_mode(self): config = { diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 56a08a418b361f..42167f31567858 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -4704,7 +4704,7 @@ static PyObject * get_core_config(PyObject *self, PyObject *Py_UNUSED(args)) { PyInterpreterState *interp = _PyInterpreterState_Get(); - const _PyCoreConfig *config = &interp->core_config; + const _PyCoreConfig *config = &interp->config.core_config; return _PyCoreConfig_AsDict(config); } diff --git a/Modules/getpath.c b/Modules/getpath.c index 18df795c93fc96..c60ab76ff060a9 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -561,7 +561,8 @@ calculate_reduce_exec_prefix(PyCalculatePath *calculate, wchar_t *exec_prefix) static _PyInitError -calculate_program_full_path(const _PyCoreConfig *core_config, +calculate_program_full_path(const _PyPreConfig *pre_config, + const _PyCoreConfig *core_config, PyCalculatePath *calculate, _PyPathConfig *config) { wchar_t program_full_path[MAXPATHLEN+1]; @@ -581,8 +582,8 @@ calculate_program_full_path(const _PyCoreConfig *core_config, * other way to find a directory to start the search from. If * $PATH isn't exported, you lose. */ - if (wcschr(core_config->program_name, SEP)) { - wcsncpy(program_full_path, core_config->program_name, MAXPATHLEN); + if (wcschr(pre_config->program_name, SEP)) { + wcsncpy(program_full_path, pre_config->program_name, MAXPATHLEN); } #ifdef __APPLE__ /* On Mac OS X, if a script uses an interpreter of the form @@ -624,7 +625,7 @@ calculate_program_full_path(const _PyCoreConfig *core_config, wcsncpy(program_full_path, path, MAXPATHLEN); } - joinpath(program_full_path, core_config->program_name); + joinpath(program_full_path, pre_config->program_name); if (isxfile(program_full_path)) { break; } @@ -934,12 +935,13 @@ calculate_free(PyCalculatePath *calculate) static _PyInitError -calculate_path_impl(const _PyCoreConfig *core_config, +calculate_path_impl(const _PyPreConfig *pre_config, + const _PyCoreConfig *core_config, PyCalculatePath *calculate, _PyPathConfig *config) { _PyInitError err; - err = calculate_program_full_path(core_config, calculate, config); + err = calculate_program_full_path(pre_config, core_config, calculate, config); if (_Py_INIT_FAILED(err)) { return err; } @@ -993,7 +995,9 @@ calculate_path_impl(const _PyCoreConfig *core_config, _PyInitError -_PyPathConfig_Calculate_impl(_PyPathConfig *config, const _PyCoreConfig *core_config) +_PyPathConfig_Calculate_impl(_PyPathConfig *path_config, + const _PyPreConfig *pre_config, + const _PyCoreConfig *core_config) { PyCalculatePath calculate; memset(&calculate, 0, sizeof(calculate)); @@ -1003,7 +1007,8 @@ _PyPathConfig_Calculate_impl(_PyPathConfig *config, const _PyCoreConfig *core_co goto done; } - err = calculate_path_impl(core_config, &calculate, config); + err = calculate_path_impl(pre_config, core_config, + &calculate, path_config); if (_Py_INIT_FAILED(err)) { goto done; } diff --git a/Modules/main.c b/Modules/main.c index 8e66ddded419a3..b9633b4ae29526 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -358,7 +358,7 @@ pymain_wstrdup(_PyMain *pymain, const wchar_t *str) static int -pymain_init_cmdline_argv(_PyMain *pymain, _PyCoreConfig *config, +pymain_init_cmdline_argv(_PyMain *pymain, _PyPreConfig *preconfig, _PyCmdline *cmdline) { assert(cmdline->argv == NULL); @@ -398,8 +398,8 @@ pymain_init_cmdline_argv(_PyMain *pymain, _PyCoreConfig *config, else { program = L""; } - config->program = pymain_wstrdup(pymain, program); - if (config->program == NULL) { + preconfig->program = pymain_wstrdup(pymain, program); + if (preconfig->program == NULL) { return -1; } @@ -445,19 +445,6 @@ pymain_clear_pymain(_PyMain *pymain) #undef CLEAR } -static void -pymain_clear_config(_PyCoreConfig *config) -{ - /* Clear core config with the memory allocator - used by pymain_read_conf() */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - _PyCoreConfig_Clear(config); - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); -} - static void pymain_free(_PyMain *pymain) @@ -567,9 +554,11 @@ pymain_wstrlist_append(_PyMain *pymain, int *len, wchar_t ***list, const wchar_t Return 1 if parsing failed. Set pymain->err and return -1 on other errors. */ static int -pymain_parse_cmdline_impl(_PyMain *pymain, _PyCoreConfig *config, +pymain_parse_cmdline_impl(_PyMain *pymain, _PyPreConfig *preconfig, _PyCmdline *cmdline) { + _PyCoreConfig *config = &preconfig->core_config; + _PyOS_ResetGetOpt(); do { int longindex = -1; @@ -972,7 +961,7 @@ pymain_header(_PyMain *pymain, const _PyCoreConfig *config) static int -pymain_init_core_argv(_PyMain *pymain, _PyCoreConfig *config, _PyCmdline *cmdline) +pymain_init_core_argv(_PyMain *pymain, _PyPreConfig *preconfig, _PyCmdline *cmdline) { /* Copy argv to be able to modify it (to force -c/-m) */ int argc = pymain->argc - _PyOS_optind; @@ -1015,8 +1004,8 @@ pymain_init_core_argv(_PyMain *pymain, _PyCoreConfig *config, _PyCmdline *cmdlin argv[0] = arg0; } - config->argc = argc; - config->argv = argv; + preconfig->core_config.argc = argc; + preconfig->core_config.argv = argv; return 0; } @@ -1093,22 +1082,39 @@ pymain_run_startup(_PyMain *pymain, _PyCoreConfig *config, PyCompilerFlags *cf) static void -pymain_run_file(_PyMain *pymain, _PyCoreConfig *config, PyCompilerFlags *cf) +pymain_run_file(_PyMain *pymain, _PyMainInterpreterConfig *config, PyCompilerFlags *cf) { const wchar_t *filename = pymain->filename; FILE *fp = _Py_wfopen(filename, L"r"); if (fp == NULL) { - char *cfilename_buffer; - const char *cfilename; int err = errno; - cfilename_buffer = _Py_EncodeLocaleRaw(filename, NULL); - if (cfilename_buffer != NULL) - cfilename = cfilename_buffer; - else - cfilename = ""; - fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n", - config->program, cfilename, err, strerror(err)); - PyMem_RawFree(cfilename_buffer); + + PyObject* filename_obj = PyUnicode_FromWideChar(filename, -1); + if (filename_obj != NULL) { + PySys_FormatStderr("'%U'", filename_obj); + Py_DECREF(filename_obj); + } + else { + PySys_WriteStderr(""); + } + PySys_WriteStderr(": can't open file [Errno %d]", err); + + PyObject* errmsg_obj; + char *errmsg = strerror(err); + if (errmsg != NULL) { + errmsg_obj = PyUnicode_DecodeLocale(errmsg, "surrogateescape"); + } + else { + errmsg_obj = NULL; + } + if (errmsg_obj != NULL) { + PySys_FormatStderr(" %U\n", errmsg_obj); + Py_DECREF(errmsg_obj); + } + else { + PySys_WriteStderr("\n"); + } + pymain->status = 2; return; } @@ -1126,9 +1132,17 @@ pymain_run_file(_PyMain *pymain, _PyCoreConfig *config, PyCompilerFlags *cf) struct _Py_stat_struct sb; if (_Py_fstat_noraise(fileno(fp), &sb) == 0 && S_ISDIR(sb.st_mode)) { - fprintf(stderr, - "%ls: '%ls' is a directory, cannot continue\n", - config->program, filename); + PySys_FormatStderr("%U: ", config->program); + PyObject* filename_obj = PyUnicode_FromWideChar(filename, -1); + if (filename_obj != NULL) { + PySys_FormatStderr("'%U'", filename_obj); + Py_DECREF(filename_obj); + } + else { + PySys_WriteStderr(""); + } + PySys_WriteStderr(" is a directory, cannot continue\n"); + pymain->status = 1; fclose(fp); return; @@ -1217,15 +1231,15 @@ pymain_repl(_PyMain *pymain, _PyCoreConfig *config, PyCompilerFlags *cf) Return 0 on success. Set pymain->err and return -1 on failure. */ static int -pymain_parse_cmdline(_PyMain *pymain, _PyCoreConfig *config, +pymain_parse_cmdline(_PyMain *pymain, _PyPreConfig *preconfig, _PyCmdline *cmdline) { - int res = pymain_parse_cmdline_impl(pymain, config, cmdline); + int res = pymain_parse_cmdline_impl(pymain, preconfig, cmdline); if (res < 0) { return -1; } if (res) { - pymain_usage(1, config->program); + pymain_usage(1, preconfig->program); pymain->status = 2; return 1; } @@ -1246,26 +1260,27 @@ pymain_parse_cmdline(_PyMain *pymain, _PyCoreConfig *config, Return 1 if Python is done and must exit. Set pymain->err and return -1 on error. */ static int -pymain_read_conf_impl(_PyMain *pymain, _PyCoreConfig *config, +pymain_read_conf_impl(_PyMain *pymain, _PyPreConfig *preconfig, _PyCmdline *cmdline) { _PyInitError err; - int res = pymain_parse_cmdline(pymain, config, cmdline); + int res = pymain_parse_cmdline(pymain, preconfig, cmdline); if (res != 0) { return res; } - if (pymain_init_core_argv(pymain, config, cmdline) < 0) { + if (pymain_init_core_argv(pymain, preconfig, cmdline) < 0) { return -1; } - err = _PyCoreConfig_Read(config); + err = _PyPreConfig_Read(preconfig); if (_Py_INIT_FAILED(err)) { pymain->err = err; return -1; } + _PyCoreConfig *config = &preconfig->core_config; if (config->use_environment) { err = cmdline_init_env_warnoptions(pymain, config, cmdline); if (_Py_INIT_FAILED(err)) { @@ -1286,19 +1301,19 @@ pymain_read_conf_impl(_PyMain *pymain, _PyCoreConfig *config, /* Read the configuration and initialize the LC_CTYPE locale: enable UTF-8 mode (PEP 540) and/or coerce the C locale (PEP 538). */ static int -pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config, - _PyCmdline *cmdline) +pymain_read_conf(_PyMain *pymain, _PyPreConfig *preconfig, _PyCmdline *cmdline) { int init_utf8_mode = Py_UTF8Mode; #ifdef MS_WINDOWS int init_legacy_encoding = Py_LegacyWindowsFSEncodingFlag; #endif - _PyCoreConfig save_config = _PyCoreConfig_INIT; + _PyPreConfig save_config = _PyPreConfig_INIT; + _PyCoreConfig *config = &preconfig->core_config; int res = -1; int locale_coerced = 0; int loops = 0; - if (_PyCoreConfig_Copy(&save_config, config) < 0) { + if (_PyPreConfig_Copy(&save_config, preconfig) < 0) { pymain->err = _Py_INIT_NO_MEMORY(); goto done; } @@ -1325,11 +1340,11 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config, Py_LegacyWindowsFSEncodingFlag = config->legacy_windows_fs_encoding; #endif - if (pymain_init_cmdline_argv(pymain, config, cmdline) < 0) { + if (pymain_init_cmdline_argv(pymain, preconfig, cmdline) < 0) { goto done; } - int conf_res = pymain_read_conf_impl(pymain, config, cmdline); + int conf_res = pymain_read_conf_impl(pymain, preconfig, cmdline); if (conf_res != 0) { res = conf_res; goto done; @@ -1371,7 +1386,7 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config, just keep UTF-8 Mode value. */ int new_utf8_mode = config->utf8_mode; int new_coerce_c_locale = config->coerce_c_locale; - if (_PyCoreConfig_Copy(config, &save_config) < 0) { + if (_PyPreConfig_Copy(preconfig, &save_config) < 0) { pymain->err = _Py_INIT_NO_MEMORY(); goto done; } @@ -1386,7 +1401,7 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config, res = 0; done: - _PyCoreConfig_Clear(&save_config); + _PyPreConfig_Clear(&save_config); Py_UTF8Mode = init_utf8_mode ; #ifdef MS_WINDOWS Py_LegacyWindowsFSEncodingFlag = init_legacy_encoding; @@ -1398,6 +1413,7 @@ pymain_read_conf(_PyMain *pymain, _PyCoreConfig *config, void _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *config) { + _PyCoreConfig_Clear(&config->core_config); Py_CLEAR(config->argv); Py_CLEAR(config->executable); Py_CLEAR(config->prefix); @@ -1407,6 +1423,8 @@ _PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *config) Py_CLEAR(config->warnoptions); Py_CLEAR(config->xoptions); Py_CLEAR(config->module_search_path); + Py_CLEAR(config->program_name); + Py_CLEAR(config->program); Py_CLEAR(config->pycache_prefix); } @@ -1441,7 +1459,10 @@ _PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig *config, { _PyMainInterpreterConfig_Clear(config); -#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR + if (_PyCoreConfig_Copy(&config->core_config, &config2->core_config) < 0) { + return -1; + } + #define COPY_OBJ_ATTR(ATTR) \ do { \ if (config2->ATTR != NULL) { \ @@ -1452,7 +1473,6 @@ _PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig *config, } \ } while (0) - COPY_ATTR(install_signal_handlers); COPY_OBJ_ATTR(argv); COPY_OBJ_ATTR(executable); COPY_OBJ_ATTR(prefix); @@ -1462,8 +1482,9 @@ _PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig *config, COPY_OBJ_ATTR(warnoptions); COPY_OBJ_ATTR(xoptions); COPY_OBJ_ATTR(module_search_path); + COPY_OBJ_ATTR(program_name); + COPY_OBJ_ATTR(program); COPY_OBJ_ATTR(pycache_prefix); -#undef COPY_ATTR #undef COPY_OBJ_ATTR return 0; } @@ -1505,7 +1526,6 @@ _PyMainInterpreterConfig_AsDict(const _PyMainInterpreterConfig *config) } \ } while (0) - SET_ITEM_INT(install_signal_handlers); SET_ITEM_OBJ(argv); SET_ITEM_OBJ(executable); SET_ITEM_OBJ(prefix); @@ -1515,6 +1535,8 @@ _PyMainInterpreterConfig_AsDict(const _PyMainInterpreterConfig *config) SET_ITEM_OBJ(warnoptions); SET_ITEM_OBJ(xoptions); SET_ITEM_OBJ(module_search_path); + SET_ITEM_OBJ(program_name); + SET_ITEM_OBJ(program); SET_ITEM_OBJ(pycache_prefix); return dict; @@ -1529,11 +1551,12 @@ _PyMainInterpreterConfig_AsDict(const _PyMainInterpreterConfig *config) _PyInitError _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config, - const _PyCoreConfig *config) + const _PyPreConfig *preconfig) { - if (main_config->install_signal_handlers < 0) { - main_config->install_signal_handlers = config->install_signal_handlers; + if (_PyCoreConfig_Copy(&main_config->core_config, &preconfig->core_config) < 0) { + return _Py_INIT_NO_MEMORY(); } + const _PyCoreConfig *config = &main_config->core_config; if (main_config->xoptions == NULL) { main_config->xoptions = config_create_xoptions_dict(config); @@ -1542,10 +1565,10 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config, } } -#define COPY_WSTR(ATTR) \ +#define COPY_WSTR(CONFIG, ATTR) \ do { \ - if (main_config->ATTR == NULL && config->ATTR != NULL) { \ - main_config->ATTR = PyUnicode_FromWideChar(config->ATTR, -1); \ + if (main_config->ATTR == NULL && CONFIG->ATTR != NULL) { \ + main_config->ATTR = PyUnicode_FromWideChar(CONFIG->ATTR, -1); \ if (main_config->ATTR == NULL) { \ return _Py_INIT_NO_MEMORY(); \ } \ @@ -1569,21 +1592,18 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config, } if (config->_install_importlib) { - COPY_WSTR(executable); - COPY_WSTR(prefix); - COPY_WSTR(base_prefix); - COPY_WSTR(exec_prefix); - COPY_WSTR(base_exec_prefix); + COPY_WSTR(config, executable); + COPY_WSTR(config, prefix); + COPY_WSTR(config, base_prefix); + COPY_WSTR(config, exec_prefix); + COPY_WSTR(config, base_exec_prefix); COPY_WSTRLIST(main_config->module_search_path, config->nmodule_search_path, config->module_search_paths); - if (config->pycache_prefix != NULL) { - COPY_WSTR(pycache_prefix); - } else { - main_config->pycache_prefix = NULL; - } - + COPY_WSTR(preconfig, program_name); + COPY_WSTR(preconfig, program); + COPY_WSTR(preconfig, pycache_prefix); } return _Py_INIT_OK(); @@ -1592,32 +1612,12 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config, } -static int -pymain_init_python_main(_PyMain *pymain, _PyCoreConfig *config, - PyInterpreterState *interp) -{ - _PyInitError err; - - _PyMainInterpreterConfig main_config = _PyMainInterpreterConfig_INIT; - err = _PyMainInterpreterConfig_Read(&main_config, config); - if (!_Py_INIT_FAILED(err)) { - err = _Py_InitializeMainInterpreter(interp, &main_config); - } - _PyMainInterpreterConfig_Clear(&main_config); - - if (_Py_INIT_FAILED(err)) { - pymain->err = err; - return -1; - } - return 0; -} - - static int pymain_run_python(_PyMain *pymain, PyInterpreterState *interp) { int res = 0; - _PyCoreConfig *config = &interp->core_config; + _PyMainInterpreterConfig *main_config = &interp->config; + _PyCoreConfig *config = &main_config->core_config; PyObject *main_importer_path = NULL; if (pymain->filename != NULL) { @@ -1668,7 +1668,7 @@ pymain_run_python(_PyMain *pymain, PyInterpreterState *interp) pymain->status = (sts != 0); } else if (pymain->filename != NULL) { - pymain_run_file(pymain, config, &cf); + pymain_run_file(pymain, main_config, &cf); } else { pymain_run_stdin(pymain, config, &cf); @@ -1683,15 +1683,14 @@ pymain_run_python(_PyMain *pymain, PyInterpreterState *interp) static int -pymain_cmdline_impl(_PyMain *pymain, _PyCoreConfig *config, - _PyCmdline *cmdline) +pymain_cmdline_impl(_PyMain *pymain, _PyPreConfig *preconfig, _PyCmdline *cmdline) { pymain->err = _PyRuntime_Initialize(); if (_Py_INIT_FAILED(pymain->err)) { return -1; } - int res = pymain_read_conf(pymain, config, cmdline); + int res = pymain_read_conf(pymain, preconfig, cmdline); if (res < 0) { return -1; } @@ -1701,7 +1700,7 @@ pymain_cmdline_impl(_PyMain *pymain, _PyCoreConfig *config, } if (cmdline->print_help) { - pymain_usage(0, config->program); + pymain_usage(0, preconfig->program); return 1; } @@ -1734,7 +1733,7 @@ pymain_cmdline_impl(_PyMain *pymain, _PyCoreConfig *config, _PyCmdline is a temporary structure used to prioritize these variables. */ static int -pymain_cmdline(_PyMain *pymain, _PyCoreConfig *config) +pymain_cmdline(_PyMain *pymain, _PyPreConfig *preconfig) { /* Force default allocator, since pymain_free() and pymain_clear_config() must use the same allocator than this function. */ @@ -1748,7 +1747,7 @@ pymain_cmdline(_PyMain *pymain, _PyCoreConfig *config) _PyCmdline cmdline; memset(&cmdline, 0, sizeof(cmdline)); - int res = pymain_cmdline_impl(pymain, config, &cmdline); + int res = pymain_cmdline_impl(pymain, preconfig, &cmdline); pymain_clear_cmdline(pymain, &cmdline); @@ -1766,6 +1765,9 @@ pymain_cmdline(_PyMain *pymain, _PyCoreConfig *config) static int pymain_init(_PyMain *pymain, PyInterpreterState **interp_p) { + PyMemAllocatorEx old_alloc; + int res = 0; + /* 754 requires that FP exceptions run in "no stop" mode by default, * and until C vendors implement C99's ways to control FP exceptions, * Python requires non-stop mode. Alas, some platforms enable FP @@ -1775,38 +1777,34 @@ pymain_init(_PyMain *pymain, PyInterpreterState **interp_p) fedisableexcept(FE_OVERFLOW); #endif - _PyCoreConfig local_config = _PyCoreConfig_INIT; - _PyCoreConfig *config = &local_config; + _PyPreConfig local_preconfig = _PyPreConfig_INIT; + _PyCoreConfig *config = &local_preconfig.core_config; _PyCoreConfig_GetGlobalConfig(config); - int cmd_res = pymain_cmdline(pymain, config); + int cmd_res = pymain_cmdline(pymain, &local_preconfig); if (cmd_res < 0) { _Py_FatalInitError(pymain->err); } if (cmd_res == 1) { - pymain_clear_config(config); - return 1; + res = 1; + goto done; } _PyCoreConfig_SetGlobalConfig(config); pymain_init_stdio(pymain, config); - PyInterpreterState *interp; - pymain->err = _Py_InitializeCore(&interp, config); + pymain->err = _Py_InitializeFromConfig(&local_preconfig, interp_p); if (_Py_INIT_FAILED(pymain->err)) { _Py_FatalInitError(pymain->err); } - *interp_p = interp; - - pymain_clear_config(config); - config = &interp->core_config; - if (pymain_init_python_main(pymain, config, interp) < 0) { - _Py_FatalInitError(pymain->err); - } - return 0; +done: + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + _PyPreConfig_Clear(&local_preconfig); + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + return res; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 04ca5f3344470e..4d276e4991d5e1 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3466,7 +3466,7 @@ PyObject * PyUnicode_EncodeFSDefault(PyObject *unicode) { PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); - const _PyCoreConfig *config = &interp->core_config; + const _PyCoreConfig *config = &interp->config.core_config; #if defined(__APPLE__) return _PyUnicode_AsUTF8String(unicode, config->filesystem_errors); #else @@ -3690,7 +3690,7 @@ PyObject* PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) { PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); - const _PyCoreConfig *config = &interp->core_config; + const _PyCoreConfig *config = &interp->config.core_config; #if defined(__APPLE__) return PyUnicode_DecodeUTF8Stateful(s, size, config->filesystem_errors, NULL); #else diff --git a/Programs/_freeze_importlib.c b/Programs/_freeze_importlib.c index 3f43757ecb1ff5..6a1e027362e220 100644 --- a/Programs/_freeze_importlib.c +++ b/Programs/_freeze_importlib.c @@ -76,16 +76,17 @@ main(int argc, char *argv[]) } text[text_size] = '\0'; - _PyCoreConfig config = _PyCoreConfig_INIT; - config.user_site_directory = 0; - config.site_import = 0; - config.use_environment = 0; - config.program_name = L"./_freeze_importlib"; + _PyPreConfig preconfig = _PyPreConfig_INIT; + _PyCoreConfig *config = &preconfig.core_config; + config->user_site_directory = 0; + config->site_import = 0; + config->use_environment = 0; + preconfig.program_name = L"./_freeze_importlib"; /* Don't install importlib, since it could execute outdated bytecode. */ - config._install_importlib = 0; - config._frozen = 1; + config->_install_importlib = 0; + config->_frozen = 1; - _PyInitError err = _Py_InitializeFromConfig(&config); + _PyInitError err = _Py_InitializeFromConfig(&preconfig, NULL); /* No need to call _PyCoreConfig_Clear() since we didn't allocate any memory: program_name is a constant string. */ if (_Py_INIT_FAILED(err)) { diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 22212bff52d4a1..28e9a8d69b614d 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -315,7 +315,7 @@ dump_config_impl(void) /* core config */ PyInterpreterState *interp = _PyInterpreterState_Get(); - const _PyCoreConfig *core_config = &interp->core_config; + const _PyCoreConfig *core_config = &interp->config.core_config; dict = _PyCoreConfig_AsDict(core_config); if (dict == NULL) { goto error; @@ -427,71 +427,72 @@ static int test_init_global_config(void) static int test_init_from_config(void) { /* Test _Py_InitializeFromConfig() */ - _PyCoreConfig config = _PyCoreConfig_INIT; - config.install_signal_handlers = 0; + _PyPreConfig preconfig = _PyPreConfig_INIT; + _PyCoreConfig *config = &preconfig.core_config; + config->install_signal_handlers = 0; /* FIXME: test use_environment */ putenv("PYTHONHASHSEED=42"); - config.use_hash_seed = 1; - config.hash_seed = 123; + config->use_hash_seed = 1; + config->hash_seed = 123; putenv("PYTHONMALLOC=malloc"); - config.allocator = "malloc_debug"; + config->allocator = "malloc_debug"; /* dev_mode=1 is tested in test_init_dev_mode() */ putenv("PYTHONFAULTHANDLER="); - config.faulthandler = 1; + config->faulthandler = 1; putenv("PYTHONTRACEMALLOC=0"); - config.tracemalloc = 2; + config->tracemalloc = 2; putenv("PYTHONPROFILEIMPORTTIME=0"); - config.import_time = 1; + config->import_time = 1; - config.show_ref_count = 1; - config.show_alloc_count = 1; + config->show_ref_count = 1; + config->show_alloc_count = 1; /* FIXME: test dump_refs: bpo-34223 */ putenv("PYTHONMALLOCSTATS=0"); - config.malloc_stats = 1; + config->malloc_stats = 1; /* FIXME: test coerce_c_locale and coerce_c_locale_warn */ putenv("PYTHONUTF8=0"); Py_UTF8Mode = 0; - config.utf8_mode = 1; + config->utf8_mode = 1; putenv("PYTHONPYCACHEPREFIX=env_pycache_prefix"); - config.pycache_prefix = L"conf_pycache_prefix"; + preconfig.pycache_prefix = L"conf_pycache_prefix"; Py_SetProgramName(L"./globalvar"); - config.program_name = L"./conf_program_name"; + preconfig.program_name = L"./conf_program_name"; static wchar_t* argv[2] = { L"-c", L"pass", }; - config.argc = Py_ARRAY_LENGTH(argv); - config.argv = argv; + config->argc = Py_ARRAY_LENGTH(argv); + config->argv = argv; - config.program = L"conf_program"; + preconfig.program = L"conf_program"; static wchar_t* xoptions[3] = { L"core_xoption1=3", L"core_xoption2=", L"core_xoption3", }; - config.nxoption = Py_ARRAY_LENGTH(xoptions); - config.xoptions = xoptions; + config->nxoption = Py_ARRAY_LENGTH(xoptions); + config->xoptions = xoptions; static wchar_t* warnoptions[2] = { L"default", L"error::ResourceWarning", }; - config.nwarnoption = Py_ARRAY_LENGTH(warnoptions); - config.warnoptions = warnoptions; + config->nwarnoption = Py_ARRAY_LENGTH(warnoptions); + config->warnoptions = warnoptions; /* FIXME: test module_search_path_env */ /* FIXME: test home */ @@ -499,59 +500,60 @@ static int test_init_from_config(void) putenv("PYTHONVERBOSE=0"); Py_VerboseFlag = 0; - config.verbose = 1; + config->verbose = 1; Py_NoSiteFlag = 0; - config.site_import = 0; + config->site_import = 0; Py_BytesWarningFlag = 0; - config.bytes_warning = 1; + config->bytes_warning = 1; putenv("PYTHONINSPECT="); Py_InspectFlag = 0; - config.inspect = 1; + config->inspect = 1; Py_InteractiveFlag = 0; - config.interactive = 1; + config->interactive = 1; putenv("PYTHONOPTIMIZE=0"); Py_OptimizeFlag = 1; - config.optimization_level = 2; + config->optimization_level = 2; /* FIXME: test parser_debug */ putenv("PYTHONDONTWRITEBYTECODE="); Py_DontWriteBytecodeFlag = 0; - config.write_bytecode = 0; + config->write_bytecode = 0; Py_QuietFlag = 0; - config.quiet = 1; + config->quiet = 1; putenv("PYTHONUNBUFFERED="); Py_UnbufferedStdioFlag = 0; - config.buffered_stdio = 0; + config->buffered_stdio = 0; putenv("PYTHONIOENCODING=cp424"); Py_SetStandardStreamEncoding("ascii", "ignore"); #ifdef MS_WINDOWS /* Py_SetStandardStreamEncoding() sets Py_LegacyWindowsStdioFlag to 1. Force it to 0 through the config. */ - config.legacy_windows_stdio = 0; + config->legacy_windows_stdio = 0; #endif - config.stdio_encoding = "iso8859-1"; - config.stdio_errors = "replace"; + config->stdio_encoding = "iso8859-1"; + config->stdio_errors = "replace"; putenv("PYTHONNOUSERSITE="); Py_NoUserSiteDirectory = 0; - config.user_site_directory = 0; + config->user_site_directory = 0; - config._check_hash_pycs_mode = "always"; + config->_check_hash_pycs_mode = "always"; Py_FrozenFlag = 0; - config._frozen = 1; + config->_frozen = 1; - _PyInitError err = _Py_InitializeFromConfig(&config); - /* Don't call _PyCoreConfig_Clear() since all strings are static */ + _PyInitError err = _Py_InitializeFromConfig(&preconfig, NULL); + /* Don't call _PyPreConfig_Clear() nor _PyCoreConfig_Clear(), + since all strings are static */ if (_Py_INIT_FAILED(err)) { _Py_FatalInitError(err); } @@ -604,19 +606,20 @@ static int test_init_env(void) static int test_init_isolated(void) { /* Test _PyCoreConfig.isolated=1 */ - _PyCoreConfig config = _PyCoreConfig_INIT; + _PyPreConfig preconfig = _PyPreConfig_INIT; + _PyCoreConfig *config = &preconfig.core_config; /* Set coerce_c_locale and utf8_mode to not depend on the locale */ - config.coerce_c_locale = 0; - config.utf8_mode = 0; + config->coerce_c_locale = 0; + config->utf8_mode = 0; /* Use path starting with "./" avoids a search along the PATH */ - config.program_name = L"./_testembed"; + preconfig.program_name = L"./_testembed"; Py_IsolatedFlag = 0; - config.isolated = 1; + config->isolated = 1; test_init_env_putenvs(); - _PyInitError err = _Py_InitializeFromConfig(&config); + _PyInitError err = _Py_InitializeFromConfig(&preconfig, NULL); if (_Py_INIT_FAILED(err)) { _Py_FatalInitError(err); } @@ -628,12 +631,13 @@ static int test_init_isolated(void) static int test_init_dev_mode(void) { - _PyCoreConfig config = _PyCoreConfig_INIT; + _PyPreConfig preconfig = _PyPreConfig_INIT; + _PyCoreConfig *config = &preconfig.core_config; putenv("PYTHONFAULTHANDLER="); putenv("PYTHONMALLOC="); - config.dev_mode = 1; - config.program_name = L"./_testembed"; - _PyInitError err = _Py_InitializeFromConfig(&config); + config->dev_mode = 1; + preconfig.program_name = L"./_testembed"; + _PyInitError err = _Py_InitializeFromConfig(&preconfig, NULL); if (_Py_INIT_FAILED(err)) { _Py_FatalInitError(err); } diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 14550fd233f4ff..20a0549930b178 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2759,7 +2759,7 @@ _PyBuiltin_Init(void) { PyObject *mod, *dict, *debug; - const _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config; + const _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->config.core_config; if (PyType_Ready(&PyFilter_Type) < 0 || PyType_Ready(&PyMap_Type) < 0 || diff --git a/Python/coreconfig.c b/Python/coreconfig.c index a040a865ae1ddb..37466fc3e02891 100644 --- a/Python/coreconfig.c +++ b/Python/coreconfig.c @@ -297,11 +297,8 @@ _PyCoreConfig_Clear(_PyCoreConfig *config) LIST = NULL; \ } while (0) - CLEAR(config->pycache_prefix); CLEAR(config->module_search_path_env); CLEAR(config->home); - CLEAR(config->program_name); - CLEAR(config->program); CLEAR_WSTRLIST(config->argc, config->argv); config->argc = -1; @@ -383,11 +380,8 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) COPY_ATTR(coerce_c_locale_warn); COPY_ATTR(utf8_mode); - COPY_WSTR_ATTR(pycache_prefix); COPY_WSTR_ATTR(module_search_path_env); COPY_WSTR_ATTR(home); - COPY_WSTR_ATTR(program_name); - COPY_WSTR_ATTR(program); COPY_WSTRLIST(argc, argv); COPY_WSTRLIST(nwarnoption, warnoptions); @@ -585,15 +579,15 @@ _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config) /* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__ environment variables on macOS if available. */ static _PyInitError -config_init_program_name(_PyCoreConfig *config) +config_init_program_name(_PyPreConfig *preconfig, _PyCoreConfig *config) { - assert(config->program_name == NULL); + assert(preconfig->program_name == NULL); /* If Py_SetProgramName() was called, use its value */ const wchar_t *program_name = _Py_path_config.program_name; if (program_name != NULL) { - config->program_name = _PyMem_RawWcsdup(program_name); - if (config->program_name == NULL) { + preconfig->program_name = _PyMem_RawWcsdup(program_name); + if (preconfig->program_name == NULL) { return _Py_INIT_NO_MEMORY(); } return _Py_INIT_OK(); @@ -617,7 +611,7 @@ config_init_program_name(_PyCoreConfig *config) return DECODE_LOCALE_ERR("PYTHONEXECUTABLE environment " "variable", (Py_ssize_t)len); } - config->program_name = program_name; + preconfig->program_name = program_name; return _Py_INIT_OK(); } #ifdef WITH_NEXT_FRAMEWORK @@ -633,7 +627,7 @@ config_init_program_name(_PyCoreConfig *config) return DECODE_LOCALE_ERR("__PYVENV_LAUNCHER__ environment " "variable", (Py_ssize_t)len); } - config->program_name = program_name; + preconfig->program_name = program_name; return _Py_INIT_OK(); } } @@ -641,9 +635,9 @@ config_init_program_name(_PyCoreConfig *config) #endif /* __APPLE__ */ /* Use argv[0] by default, if available */ - if (config->program != NULL) { - config->program_name = _PyMem_RawWcsdup(config->program); - if (config->program_name == NULL) { + if (preconfig->program != NULL) { + preconfig->program_name = _PyMem_RawWcsdup(preconfig->program); + if (preconfig->program_name == NULL) { return _Py_INIT_NO_MEMORY(); } return _Py_INIT_OK(); @@ -655,8 +649,8 @@ config_init_program_name(_PyCoreConfig *config) #else const wchar_t *default_program_name = L"python3"; #endif - config->program_name = _PyMem_RawWcsdup(default_program_name); - if (config->program_name == NULL) { + preconfig->program_name = _PyMem_RawWcsdup(default_program_name); + if (preconfig->program_name == NULL) { return _Py_INIT_NO_MEMORY(); } return _Py_INIT_OK(); @@ -968,22 +962,22 @@ config_init_tracemalloc(_PyCoreConfig *config) static _PyInitError -config_init_pycache_prefix(_PyCoreConfig *config) +config_init_pycache_prefix(_PyPreConfig *preconfig, _PyCoreConfig *config) { - assert(config->pycache_prefix == NULL); + assert(preconfig->pycache_prefix == NULL); const wchar_t *xoption = config_get_xoption(config, L"pycache_prefix"); if (xoption) { const wchar_t *sep = wcschr(xoption, L'='); if (sep && wcslen(sep) > 1) { - config->pycache_prefix = _PyMem_RawWcsdup(sep + 1); - if (config->pycache_prefix == NULL) { + preconfig->pycache_prefix = _PyMem_RawWcsdup(sep + 1); + if (preconfig->pycache_prefix == NULL) { return _Py_INIT_NO_MEMORY(); } } else { // -X pycache_prefix= can cancel the env var - config->pycache_prefix = NULL; + preconfig->pycache_prefix = NULL; } } else { @@ -996,7 +990,7 @@ config_init_pycache_prefix(_PyCoreConfig *config) } if (env) { - config->pycache_prefix = env; + preconfig->pycache_prefix = env; } } return _Py_INIT_OK(); @@ -1004,7 +998,7 @@ config_init_pycache_prefix(_PyCoreConfig *config) static _PyInitError -config_read_complex_options(_PyCoreConfig *config) +config_read_complex_options(_PyPreConfig *preconfig, _PyCoreConfig *config) { /* More complex options configured by env var and -X option */ if (config->faulthandler < 0) { @@ -1031,8 +1025,8 @@ config_read_complex_options(_PyCoreConfig *config) } } - if (config->pycache_prefix == NULL) { - err = config_init_pycache_prefix(config); + if (preconfig->pycache_prefix == NULL) { + err = config_init_pycache_prefix(preconfig, config); if (_Py_INIT_FAILED(err)) { return err; } @@ -1311,8 +1305,9 @@ config_init_fs_encoding(_PyCoreConfig *config) */ _PyInitError -_PyCoreConfig_Read(_PyCoreConfig *config) +_PyPreConfig_Read(_PyPreConfig *preconfig) { + _PyCoreConfig *config = &preconfig->core_config; _PyInitError err; _PyCoreConfig_GetGlobalConfig(config); @@ -1344,7 +1339,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config) config->show_alloc_count = 1; } - err = config_read_complex_options(config); + err = config_read_complex_options(preconfig, config); if (_Py_INIT_FAILED(err)) { return err; } @@ -1363,8 +1358,8 @@ _PyCoreConfig_Read(_PyCoreConfig *config) } } - if (config->program_name == NULL) { - err = config_init_program_name(config); + if (preconfig->program_name == NULL) { + err = config_init_program_name(preconfig, config); if (_Py_INIT_FAILED(err)) { return err; } @@ -1375,7 +1370,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config) } if (config->_install_importlib) { - err = _PyCoreConfig_InitPathConfig(config); + err = _PyCoreConfig_InitPathConfig(preconfig); if (_Py_INIT_FAILED(err)) { return err; } @@ -1493,10 +1488,7 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config) SET_ITEM_STR(filesystem_encoding); SET_ITEM_STR(filesystem_errors); SET_ITEM_INT(utf8_mode); - SET_ITEM_WSTR(pycache_prefix); - SET_ITEM_WSTR(program_name); SET_ITEM_WSTRLIST(argc, argv); - SET_ITEM_WSTR(program); SET_ITEM_WSTRLIST(nxoption, xoptions); SET_ITEM_WSTRLIST(nwarnoption, warnoptions); SET_ITEM_WSTR(module_search_path_env); @@ -1547,3 +1539,52 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config) #undef SET_ITEM_WSTR #undef SET_ITEM_WSTRLIST } + + +void +_PyPreConfig_Clear(_PyPreConfig *config) +{ + _PyCoreConfig_Clear(&config->core_config); + +#define CLEAR(ATTR) \ + do { \ + PyMem_RawFree(ATTR); \ + ATTR = NULL; \ + } while (0) + + CLEAR(config->pycache_prefix); + CLEAR(config->program); + CLEAR(config->program_name); + +#undef CLEAR +} + + +int +_PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2) +{ + _PyPreConfig_Clear(config); + + if (_PyCoreConfig_Copy(&config->core_config, &config2->core_config) < 0) { + return -1; + } + +#define COPY_WSTR_ATTR(ATTR) \ + do { \ + if (config2->ATTR != NULL) { \ + config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \ + if (config->ATTR == NULL) { \ + return -1; \ + } \ + } \ + } while (0) + + COPY_WSTR_ATTR(pycache_prefix); + COPY_WSTR_ATTR(program); + COPY_WSTR_ATTR(program_name); + return 0; + +#undef COPY_WSTR_ATTR +} + + diff --git a/Python/frozenmain.c b/Python/frozenmain.c index 616090965b1351..982ec0f78f3b09 100644 --- a/Python/frozenmain.c +++ b/Python/frozenmain.c @@ -41,8 +41,8 @@ Py_FrozenMain(int argc, char **argv) } } - _PyCoreConfig config = _PyCoreConfig_INIT; - config._frozen = 1; /* Suppress errors from getpath.c */ + _PyPreConfig preconfig = _PyPreConfig_INIT; + preconfig.core_config._frozen = 1; /* Suppress errors from getpath.c */ if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') inspect = 1; @@ -82,7 +82,7 @@ Py_FrozenMain(int argc, char **argv) if (argc >= 1) Py_SetProgramName(argv_copy[0]); - err = _Py_InitializeFromConfig(&config); + err = _Py_InitializeFromConfig(&preconfig, NULL); /* No need to call _PyCoreConfig_Clear() since we didn't allocate any memory: program_name is a constant string. */ if (_Py_INIT_FAILED(err)) { diff --git a/Python/import.c b/Python/import.c index f7c37aa353c8c3..8d9be265968a5c 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1622,7 +1622,7 @@ import_find_and_load(PyObject *abs_name) _Py_IDENTIFIER(_find_and_load); PyObject *mod = NULL; PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); - int import_time = interp->core_config.import_time; + int import_time = interp->config.core_config.import_time; static int import_level; static _PyTime_t accumulated; @@ -2279,7 +2279,7 @@ PyInit__imp(void) d = PyModule_GetDict(m); if (d == NULL) goto failure; - _PyCoreConfig *config = &_PyInterpreterState_Get()->core_config; + _PyCoreConfig *config = &_PyInterpreterState_Get()->config.core_config; PyObject *pyc_mode = PyUnicode_FromString(config->_check_hash_pycs_mode); if (pyc_mode == NULL) { goto failure; diff --git a/Python/pathconfig.c b/Python/pathconfig.c index 6a8688059825bf..d61ed191f6f140 100644 --- a/Python/pathconfig.c +++ b/Python/pathconfig.c @@ -66,6 +66,7 @@ _PyPathConfig_Clear(_PyPathConfig *config) /* Calculate the path configuration: initialize path_config from core_config */ static _PyInitError _PyPathConfig_Calculate(_PyPathConfig *path_config, + const _PyPreConfig *pre_config, const _PyCoreConfig *core_config) { _PyInitError err; @@ -76,7 +77,7 @@ _PyPathConfig_Calculate(_PyPathConfig *path_config, /* Calculate program_full_path, prefix, exec_prefix (Unix) or dll_path (Windows), and module_search_path */ - err = _PyPathConfig_Calculate_impl(&new_config, core_config); + err = _PyPathConfig_Calculate_impl(&new_config, pre_config, core_config); if (_Py_INIT_FAILED(err)) { goto err; } @@ -86,7 +87,7 @@ _PyPathConfig_Calculate(_PyPathConfig *path_config, err = _Py_INIT_NO_MEMORY(); goto err; } - if (copy_wstr(&new_config.program_name, core_config->program_name) < 0) { + if (copy_wstr(&new_config.program_name, pre_config->program_name) < 0) { err = _Py_INIT_NO_MEMORY(); goto err; } @@ -187,8 +188,10 @@ wstrlist_join(wchar_t sep, int count, wchar_t **list) /* Set the global path configuration from core_config. */ _PyInitError -_PyCoreConfig_SetPathConfig(const _PyCoreConfig *core_config) +_PyPreConfig_SetPathConfig(const _PyPreConfig *pre_config) { + const _PyCoreConfig *core_config = &pre_config->core_config; + PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); @@ -217,7 +220,7 @@ _PyCoreConfig_SetPathConfig(const _PyCoreConfig *core_config) goto no_memory; } #endif - if (copy_wstr(&path_config.program_name, core_config->program_name) < 0) { + if (copy_wstr(&path_config.program_name, pre_config->program_name) < 0) { goto no_memory; } if (copy_wstr(&path_config.home, core_config->home) < 0) { @@ -286,12 +289,13 @@ core_config_init_module_search_paths(_PyCoreConfig *config, static _PyInitError -_PyCoreConfig_CalculatePathConfig(_PyCoreConfig *config) +_PyCoreConfig_CalculatePathConfig(_PyPreConfig *preconfig, + _PyCoreConfig *config) { _PyPathConfig path_config = _PyPathConfig_INIT; _PyInitError err; - err = _PyPathConfig_Calculate(&path_config, config); + err = _PyPathConfig_Calculate(&path_config, preconfig, config); if (_Py_INIT_FAILED(err)) { goto error; } @@ -355,8 +359,10 @@ _PyCoreConfig_CalculatePathConfig(_PyCoreConfig *config) _PyInitError -_PyCoreConfig_InitPathConfig(_PyCoreConfig *config) +_PyCoreConfig_InitPathConfig(_PyPreConfig *preconfig) { + _PyCoreConfig *config = &preconfig->core_config; + /* Do we need to calculate the path? */ if ((config->nmodule_search_path < 0) || (config->executable == NULL) @@ -366,7 +372,7 @@ _PyCoreConfig_InitPathConfig(_PyCoreConfig *config) #endif || (config->exec_prefix == NULL)) { - _PyInitError err = _PyCoreConfig_CalculatePathConfig(config); + _PyInitError err = _PyCoreConfig_CalculatePathConfig(preconfig, config); if (_Py_INIT_FAILED(err)) { return err; } @@ -396,23 +402,23 @@ pathconfig_global_init(void) } _PyInitError err; - _PyCoreConfig config = _PyCoreConfig_INIT; + _PyPreConfig preconfig = _PyPreConfig_INIT; - err = _PyCoreConfig_Read(&config); + err = _PyPreConfig_Read(&preconfig); if (_Py_INIT_FAILED(err)) { goto error; } - err = _PyCoreConfig_SetPathConfig(&config); + err = _PyPreConfig_SetPathConfig(&preconfig); if (_Py_INIT_FAILED(err)) { goto error; } - _PyCoreConfig_Clear(&config); + _PyPreConfig_Clear(&preconfig); return; error: - _PyCoreConfig_Clear(&config); + _PyPreConfig_Clear(&preconfig); _Py_FatalInitError(err); } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 58e16473100e3a..0328f009f41ead 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -449,7 +449,7 @@ _Py_SetLocaleFromEnv(int category) /* Global initializations. Can be undone by Py_Finalize(). Don't call this twice without an intervening Py_Finalize() call. - Every call to _Py_InitializeCore, Py_Initialize or Py_InitializeEx + Every call to _Py_InitializeFromConfig, Py_Initialize or Py_InitializeEx must have a corresponding call to Py_Finalize. Locking: you must hold the interpreter lock while calling these APIs. @@ -460,8 +460,10 @@ _Py_SetLocaleFromEnv(int category) static _PyInitError _Py_Initialize_ReconfigureCore(PyInterpreterState *interp, - const _PyCoreConfig *core_config) + const _PyPreConfig *pre_config) { + const _PyCoreConfig *core_config = &pre_config->core_config; + if (core_config->allocator != NULL) { const char *allocator = _PyMem_GetAllocatorsName(); if (allocator == NULL || strcmp(core_config->allocator, allocator) != 0) { @@ -472,13 +474,13 @@ _Py_Initialize_ReconfigureCore(PyInterpreterState *interp, _PyCoreConfig_SetGlobalConfig(core_config); - if (_PyCoreConfig_Copy(&interp->core_config, core_config) < 0) { - return _Py_INIT_ERR("failed to copy core config"); + if (_PyCoreConfig_Copy(&interp->config.core_config, core_config) < 0) { + return _Py_INIT_NO_MEMORY(); } - core_config = &interp->core_config; + core_config = &interp->config.core_config; if (core_config->_install_importlib) { - _PyInitError err = _PyCoreConfig_SetPathConfig(core_config); + _PyInitError err = _PyPreConfig_SetPathConfig(pre_config); if (_Py_INIT_FAILED(err)) { return err; } @@ -504,12 +506,12 @@ _Py_Initialize_ReconfigureCore(PyInterpreterState *interp, * to the Python C API (unless the API is explicitly listed as being * safe to call without calling Py_Initialize first) * - * The caller is responsible to call _PyCoreConfig_Read(). + * The caller is responsible to call _PyPreConfig_Read(). */ static _PyInitError -_Py_InitializeCore_impl(PyInterpreterState **interp_p, - const _PyCoreConfig *core_config) +_Py_InitializeCore_impl(const _PyPreConfig *pre_config, + PyInterpreterState **interp_p) { PyInterpreterState *interp; _PyInitError err; @@ -528,13 +530,14 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p, } *interp_p = interp; - return _Py_Initialize_ReconfigureCore(interp, core_config); + return _Py_Initialize_ReconfigureCore(interp, pre_config); } if (_PyRuntime.initialized) { return _Py_INIT_ERR("main interpreter already initialized"); } + const _PyCoreConfig *core_config = &pre_config->core_config; _PyCoreConfig_SetGlobalConfig(core_config); err = _PyRuntime_Initialize(); @@ -575,10 +578,10 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p, } *interp_p = interp; - if (_PyCoreConfig_Copy(&interp->core_config, core_config) < 0) { - return _Py_INIT_ERR("failed to copy core config"); + if (_PyCoreConfig_Copy(&interp->config.core_config, core_config) < 0) { + return _Py_INIT_NO_MEMORY(); } - core_config = &interp->core_config; + core_config = &interp->config.core_config; PyThreadState *tstate = PyThreadState_New(interp); if (tstate == NULL) @@ -676,7 +679,7 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p, return _Py_INIT_ERR("can't init context"); if (core_config->_install_importlib) { - err = _PyCoreConfig_SetPathConfig(core_config); + err = _PyPreConfig_SetPathConfig(pre_config); if (_Py_INIT_FAILED(err)) { return err; } @@ -695,44 +698,6 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p, return _Py_INIT_OK(); } -_PyInitError -_Py_InitializeCore(PyInterpreterState **interp_p, - const _PyCoreConfig *src_config) -{ - assert(src_config != NULL); - - PyMemAllocatorEx old_alloc; - _PyInitError err; - - /* Copy the configuration, since _PyCoreConfig_Read() modifies it - (and the input configuration is read only). */ - _PyCoreConfig config = _PyCoreConfig_INIT; - - /* Set LC_CTYPE to the user preferred locale */ - _Py_SetLocaleFromEnv(LC_CTYPE); - - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - if (_PyCoreConfig_Copy(&config, src_config) >= 0) { - err = _PyCoreConfig_Read(&config); - } - else { - err = _Py_INIT_ERR("failed to copy core config"); - } - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - if (_Py_INIT_FAILED(err)) { - goto done; - } - - err = _Py_InitializeCore_impl(interp_p, &config); - -done: - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - _PyCoreConfig_Clear(&config); - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - return err; -} /* Py_Initialize() has already been called: update the main interpreter configuration. Example of bpo-34008: Py_Main() called after @@ -774,7 +739,7 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp, return _Py_INIT_ERR("failed to copy main interpreter config"); } config = &interp->config; - _PyCoreConfig *core_config = &interp->core_config; + const _PyCoreConfig *core_config = &config->core_config; if (_PyRuntime.initialized) { return _Py_ReconfigureMainInterpreter(interp, config); @@ -814,7 +779,7 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp, return err; } - if (interp->config.install_signal_handlers) { + if (interp->config.core_config.install_signal_handlers) { err = initsigs(); /* Signal handling stuff, including initintr() */ if (_Py_INIT_FAILED(err)) { return err; @@ -865,27 +830,70 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp, #undef _INIT_DEBUG_PRINT + _PyInitError -_Py_InitializeFromConfig(const _PyCoreConfig *config) +_Py_InitializeCore(const _PyPreConfig *src_preconfig, + _PyMainInterpreterConfig *main_config, + PyInterpreterState **interp_p) { - PyInterpreterState *interp = NULL; + assert(src_preconfig != NULL); + _PyInitError err; - err = _Py_InitializeCore(&interp, config); + PyMemAllocatorEx old_alloc; + _PyPreConfig local_preconfig = _PyPreConfig_INIT; + + /* Set LC_CTYPE to the user preferred locale */ + _Py_SetLocaleFromEnv(LC_CTYPE); + + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + if (_PyPreConfig_Copy(&local_preconfig, src_preconfig) >= 0) { + err = _PyPreConfig_Read(&local_preconfig); + } + else { + err = _Py_INIT_NO_MEMORY(); + } + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + if (_Py_INIT_FAILED(err)) { - return err; + goto done; } - config = &interp->core_config; - _PyMainInterpreterConfig main_config = _PyMainInterpreterConfig_INIT; - err = _PyMainInterpreterConfig_Read(&main_config, config); - if (!_Py_INIT_FAILED(err)) { - err = _Py_InitializeMainInterpreter(interp, &main_config); + err = _Py_InitializeCore_impl(&local_preconfig, interp_p); + if (_Py_INIT_FAILED(err)) { + goto done; } - _PyMainInterpreterConfig_Clear(&main_config); + + err = _PyMainInterpreterConfig_Read(main_config, &local_preconfig); + +done: + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + _PyPreConfig_Clear(&local_preconfig); + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + return err; +} + + +_PyInitError +_Py_InitializeFromConfig(const _PyPreConfig *preconfig, + PyInterpreterState **interp_p) +{ + _PyMainInterpreterConfig local_main_config = _PyMainInterpreterConfig_INIT; + PyInterpreterState *interp = NULL; + _PyInitError err; + + err = _Py_InitializeCore(preconfig, &local_main_config, &interp); if (_Py_INIT_FAILED(err)) { - return err; + goto done; } - return _Py_INIT_OK(); + if (interp_p != NULL) { + *interp_p = interp; + } + + err = _Py_InitializeMainInterpreter(interp, &local_main_config); + +done: + _PyMainInterpreterConfig_Clear(&local_main_config); + return err; } @@ -898,12 +906,10 @@ Py_InitializeEx(int install_sigs) } _PyInitError err; - _PyCoreConfig config = _PyCoreConfig_INIT; - config.install_signal_handlers = install_sigs; - - err = _Py_InitializeFromConfig(&config); - _PyCoreConfig_Clear(&config); + _PyPreConfig config = _PyPreConfig_INIT; + config.core_config.install_signal_handlers = install_sigs; + err = _Py_InitializeFromConfig(&config, NULL); if (_Py_INIT_FAILED(err)) { _Py_FatalInitError(err); } @@ -1014,13 +1020,13 @@ Py_FinalizeEx(void) /* Copy the core config, PyInterpreterState_Delete() free the core config memory */ #ifdef Py_REF_DEBUG - int show_ref_count = interp->core_config.show_ref_count; + int show_ref_count = interp->config.core_config.show_ref_count; #endif #ifdef Py_TRACE_REFS - int dump_refs = interp->core_config.dump_refs; + int dump_refs = interp->config.core_config.dump_refs; #endif #ifdef WITH_PYMALLOC - int malloc_stats = interp->core_config.malloc_stats; + int malloc_stats = interp->config.core_config.malloc_stats; #endif /* Remaining threads (e.g. daemon threads) will automatically exit @@ -1248,19 +1254,19 @@ new_interpreter(PyThreadState **tstate_p) _PyCoreConfig *core_config; _PyMainInterpreterConfig *config; if (save_tstate != NULL) { - core_config = &save_tstate->interp->core_config; + core_config = &save_tstate->interp->config.core_config; config = &save_tstate->interp->config; } else { /* No current thread state, copy from the main interpreter */ PyInterpreterState *main_interp = PyInterpreterState_Main(); - core_config = &main_interp->core_config; + core_config = &main_interp->config.core_config; config = &main_interp->config; } - if (_PyCoreConfig_Copy(&interp->core_config, core_config) < 0) { - return _Py_INIT_ERR("failed to copy core config"); + if (_PyCoreConfig_Copy(&interp->config.core_config, core_config) < 0) { + return _Py_INIT_NO_MEMORY(); } - core_config = &interp->core_config; + core_config = &interp->config.core_config; if (_PyMainInterpreterConfig_Copy(&interp->config, config) < 0) { return _Py_INIT_ERR("failed to copy main interpreter config"); } @@ -1464,7 +1470,7 @@ add_main_module(PyInterpreterState *interp) static _PyInitError initfsencoding(PyInterpreterState *interp) { - _PyCoreConfig *config = &interp->core_config; + _PyCoreConfig *config = &interp->config.core_config; char *encoding = get_codec_name(config->filesystem_encoding); if (encoding == NULL) { @@ -1669,7 +1675,7 @@ init_sys_streams(PyInterpreterState *interp) int fd; PyObject * encoding_attr; _PyInitError res = _Py_INIT_OK(); - _PyCoreConfig *config = &interp->core_config; + _PyCoreConfig *config = &interp->config.core_config; char *codec_name = get_codec_name(config->stdio_encoding); if (codec_name == NULL) { diff --git a/Python/pystate.c b/Python/pystate.c index f86f5a96f07450..f3fb843453eca5 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -148,7 +148,6 @@ PyInterpreterState_New(void) interp->codec_error_registry = NULL; interp->codecs_initialized = 0; interp->fscodec_initialized = 0; - interp->core_config = _PyCoreConfig_INIT; interp->config = _PyMainInterpreterConfig_INIT; interp->importlib = NULL; interp->import_func = NULL; @@ -205,7 +204,6 @@ PyInterpreterState_Clear(PyInterpreterState *interp) for (p = interp->tstate_head; p != NULL; p = p->next) PyThreadState_Clear(p); HEAD_UNLOCK(); - _PyCoreConfig_Clear(&interp->core_config); _PyMainInterpreterConfig_Clear(&interp->config); Py_CLEAR(interp->codec_search_path); Py_CLEAR(interp->codec_search_cache); @@ -623,7 +621,7 @@ _PyState_ClearModules(void) void PyThreadState_Clear(PyThreadState *tstate) { - int verbose = tstate->interp->core_config.verbose; + int verbose = tstate->interp->config.core_config.verbose; if (verbose && tstate->frame != NULL) fprintf(stderr, diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 1bf822ceadb483..fdaf5ca1cc6d37 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -91,7 +91,7 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags * PyCompilerFlags local_flags; int nomem_count = 0; #ifdef Py_REF_DEBUG - int show_ref_count = _PyInterpreterState_Get()->core_config.show_ref_count; + int show_ref_count = _PyInterpreterState_Get()->config.core_config.show_ref_count; #endif filename = PyUnicode_DecodeFSDefault(filename_str); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 2284e88d4c1180..34682fdfb724e7 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -385,7 +385,7 @@ static PyObject * sys_getfilesystemencoding(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); - const _PyCoreConfig *config = &interp->core_config; + const _PyCoreConfig *config = &interp->config.core_config; return PyUnicode_FromString(config->filesystem_encoding); } @@ -400,7 +400,7 @@ static PyObject * sys_getfilesystemencodeerrors(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); - const _PyCoreConfig *config = &interp->core_config; + const _PyCoreConfig *config = &interp->config.core_config; return PyUnicode_FromString(config->filesystem_errors); } @@ -1142,7 +1142,7 @@ static PyObject * sys_enablelegacywindowsfsencoding(PyObject *self) { PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); - _PyCoreConfig *config = &interp->core_config; + _PyCoreConfig *config = &interp->config.core_config; /* Set the filesystem encoding to mbcs/replace (PEP 529) */ char *encoding = _PyMem_RawStrdup("mbcs"); @@ -2076,7 +2076,7 @@ make_flags(void) { int pos = 0; PyObject *seq; - const _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config; + const _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->config.core_config; seq = PyStructSequence_New(&FlagsType); if (seq == NULL) @@ -2476,7 +2476,7 @@ _PySys_BeginInit(PyObject **sysmod) int _PySys_EndInit(PyObject *sysdict, PyInterpreterState *interp) { - const _PyCoreConfig *core_config = &interp->core_config; + const _PyCoreConfig *core_config = &interp->config.core_config; const _PyMainInterpreterConfig *config = &interp->config; int res;