]> granicus.if.org Git - python/commitdiff
bpo-36301: Remove _PyCoreConfig.preconfig (GH-12546)
authorVictor Stinner <vstinner@redhat.com>
Tue, 26 Mar 2019 01:31:11 +0000 (02:31 +0100)
committerGitHub <noreply@github.com>
Tue, 26 Mar 2019 01:31:11 +0000 (02:31 +0100)
* Replace _PyCoreConfig.preconfig with 3 new fields in _PyCoreConfig:
  isolated, use_environment, dev_mode.
* Add _PyPreCmdline.dev_mode.
* Add _Py_PreInitializeFromPreConfigInPlace().

13 files changed:
Include/cpython/coreconfig.h
Include/cpython/pylifecycle.h
Include/internal/pycore_coreconfig.h
Include/internal/pycore_pylifecycle.h
Lib/test/test_embed.py
Modules/main.c
Programs/_freeze_importlib.c
Programs/_testembed.c
Python/coreconfig.c
Python/pathconfig.c
Python/preconfig.c
Python/pylifecycle.c
Python/sysmodule.c

index 621a09fa79ec5df0996490059e9d60a5706301dd..827a19a145d0be877808c3d740b11284662f5823 100644 (file)
@@ -123,7 +123,9 @@ typedef struct {
 /* --- _PyCoreConfig ---------------------------------------------- */
 
 typedef struct {
-    _PyPreConfig preconfig;
+    int isolated;
+    int use_environment;
+    int dev_mode;
 
     /* Install signal handlers? Yes by default. */
     int install_signal_handlers;
@@ -375,7 +377,9 @@ typedef struct {
 #define _PyCoreConfig_INIT \
     (_PyCoreConfig){ \
         _PyCoreConfig_WINDOWS_INIT \
-        .preconfig = _PyPreConfig_INIT, \
+        .isolated = -1, \
+        .use_environment = -1, \
+        .dev_mode = -1, \
         .install_signal_handlers = 1, \
         .use_hash_seed = -1, \
         .faulthandler = -1, \
index 5f3a522a600a5d6d0559099cfdb3914a1f5b8513..e32e54cba07fdd1c9e41678469722c8c242ca4ca 100644 (file)
@@ -16,7 +16,7 @@ PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding,
 
 PyAPI_FUNC(_PyInitError) _Py_PreInitialize(void);
 PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromPreConfig(
-    _PyPreConfig *preconfig);
+    const _PyPreConfig *preconfig);
 PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromConfig(
     const _PyCoreConfig *coreconfig);
 
index 829ff3109fda92525780c67704718fc1ab96600f..d79f590d68d27e1182d2c424e7e598aa9b014a23 100644 (file)
@@ -16,12 +16,14 @@ typedef struct {
     _PyWstrList xoptions;     /* "-X value" option */
     int use_environment;      /* -E option */
     int isolated;             /* -I option */
+    int dev_mode;             /* -X dev and PYTHONDEVMODE */
 } _PyPreCmdline;
 
 #define _PyPreCmdline_INIT \
     (_PyPreCmdline){ \
         .use_environment = -1, \
-        .isolated = -1}
+        .isolated = -1, \
+        .dev_mode = -1}
 /* Note: _PyPreCmdline_INIT sets other fields to 0/NULL */
 
 PyAPI_FUNC(void) _PyPreCmdline_Clear(_PyPreCmdline *cmdline);
@@ -112,7 +114,7 @@ PyAPI_FUNC(void) _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config);
 PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config);
 PyAPI_FUNC(_PyInitError) _PyCoreConfig_ReadFromArgv(_PyCoreConfig *config,
     const _PyArgv *args);
-PyAPI_FUNC(_PyInitError) _PyCoreConfig_Write(const _PyCoreConfig *config);
+PyAPI_FUNC(void) _PyCoreConfig_Write(const _PyCoreConfig *config);
 
 /* --- _PyMainInterpreterConfig ----------------------------------- */
 
index 9514b1c46a2a75dc2df49b55ab768bf3e66cc93b..3214d6b06bd6662f02813498d851cd8efd6ec603 100644 (file)
@@ -77,6 +77,9 @@ extern void _PyGILState_Fini(void);
 
 PyAPI_FUNC(void) _PyGC_DumpShutdownStats(void);
 
+PyAPI_FUNC(_PyInitError) _Py_PreInitializeInPlace(
+    _PyPreConfig *config);
+
 #ifdef __cplusplus
 }
 #endif
index 6e145a5aa136cd468c13829705525aa5fdb6ae3e..ff3cfb1ea49dedb392bf5d443188be05142ebc6c 100644 (file)
@@ -272,12 +272,19 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
         'allocator': None,
         'coerce_c_locale': 0,
         'coerce_c_locale_warn': 0,
-        'dev_mode': 0,
-        'isolated': 0,
-        'use_environment': 1,
         'utf8_mode': 0,
     }
+    COPY_PRE_CONFIG = [
+        'dev_mode',
+        'isolated',
+        'use_environment',
+    ]
+
     DEFAULT_CORE_CONFIG = {
+        'isolated': 0,
+        'use_environment': 1,
+        'dev_mode': 0,
+
         'install_signal_handlers': 1,
         'use_hash_seed': 0,
         'hash_seed': 0,
@@ -363,8 +370,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
         '_Py_HasFileSystemDefaultEncodeErrors': 0,
     }
     COPY_GLOBAL_PRE_CONFIG = [
-        ('Py_IgnoreEnvironmentFlag', 'use_environment', True),
-        ('Py_IsolatedFlag', 'isolated'),
         ('Py_UTF8Mode', 'utf8_mode'),
     ]
     COPY_GLOBAL_CONFIG = [
@@ -376,8 +381,10 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
         ('Py_FileSystemDefaultEncodeErrors', 'filesystem_errors'),
         ('Py_FileSystemDefaultEncoding', 'filesystem_encoding'),
         ('Py_FrozenFlag', '_frozen'),
+        ('Py_IgnoreEnvironmentFlag', 'use_environment', True),
         ('Py_InspectFlag', 'inspect'),
         ('Py_InteractiveFlag', 'interactive'),
+        ('Py_IsolatedFlag', 'isolated'),
         ('Py_NoSiteFlag', 'site_import', True),
         ('Py_NoUserSiteDirectory', 'user_site_directory', True),
         ('Py_OptimizeFlag', 'optimization_level'),
@@ -415,7 +422,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
         expected['xoptions'] = self.main_xoptions(core_config['xoptions'])
         self.assertEqual(main_config, expected)
 
-    def get_expected_config(self, expected, expected_preconfig, env):
+    def get_expected_config(self, expected, env):
         expected = dict(self.DEFAULT_CORE_CONFIG, **expected)
 
         code = textwrap.dedent('''
@@ -443,7 +450,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
         # when test_embed is run from a venv (bpo-35313)
         args = (sys.executable, '-S', '-c', code)
         env = dict(env)
-        if not expected_preconfig['isolated']:
+        if not expected['isolated']:
             env['PYTHONCOERCECLOCALE'] = '0'
             env['PYTHONUTF8'] = '0'
         proc = subprocess.run(args, env=env,
@@ -509,7 +516,10 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
         config = json.loads(out)
 
         expected_preconfig = dict(self.DEFAULT_PRE_CONFIG, **expected_preconfig)
-        expected_config = self.get_expected_config(expected_config, expected_preconfig, env)
+        expected_config = self.get_expected_config(expected_config, env)
+        for key in self.COPY_PRE_CONFIG:
+            if key not in expected_preconfig:
+                expected_preconfig[key] = expected_config[key]
 
         self.check_core_config(config, expected_config)
         self.check_pre_config(config, expected_preconfig)
@@ -617,35 +627,36 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
 
     def test_init_env_dev_mode(self):
         preconfig = dict(self.INIT_ENV_PRECONFIG,
-                      allocator='debug',
-                      dev_mode=1)
+                      allocator='debug')
         config = dict(self.INIT_ENV_CONFIG,
                       dev_mode=1)
         self.check_config("init_env_dev_mode", config, preconfig)
 
-    def test_init_env_dev_mode(self):
+    def test_init_env_dev_mode_alloc(self):
         preconfig = dict(self.INIT_ENV_PRECONFIG,
-                         allocator='malloc',
-                         dev_mode=1)
-        config = dict(self.INIT_ENV_CONFIG)
+                         allocator='malloc')
+        config = dict(self.INIT_ENV_CONFIG,
+                      dev_mode=1)
         self.check_config("init_env_dev_mode_alloc", config, preconfig)
 
     def test_init_dev_mode(self):
         preconfig = {
             'allocator': 'debug',
-            'dev_mode': 1,
         }
         config = {
             'faulthandler': 1,
+            'dev_mode': 1,
         }
         self.check_config("init_dev_mode", config, preconfig)
 
     def test_init_isolated(self):
         preconfig = {
-            'isolated': 1,
-            'use_environment': 0,
+            'isolated': 0,
+            'use_environment': 1,
         }
         config = {
+            'isolated': 1,
+            'use_environment': 0,
             'user_site_directory': 0,
         }
         self.check_config("init_isolated", config, preconfig)
index 46bc72af46dd0cc7a5aa61e3d24a361535438cb2..9fcc76e58a6afcb280ac157d22ccb091a10fc191 100644 (file)
@@ -294,7 +294,7 @@ pymain_init_preconfig(const _PyArgv *args)
         goto done;
     }
 
-    err = _Py_PreInitializeFromPreConfig(&config);
+    err = _Py_PreInitializeInPlace(&config);
 
 done:
     _PyPreConfig_Clear(&config);
@@ -311,11 +311,6 @@ pymain_init_coreconfig(_PyCoreConfig *config, const _PyArgv *args,
         return err;
     }
 
-    err = _PyCoreConfig_Write(config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
-    }
-
     return _Py_InitializeCore(interp_p, config);
 }
 
@@ -483,7 +478,7 @@ pymain_header(const _PyCoreConfig *config)
 static void
 pymain_import_readline(const _PyCoreConfig *config)
 {
-    if (config->preconfig.isolated) {
+    if (config->isolated) {
         return;
     }
     if (!config->inspect && RUN_CODE(config)) {
@@ -655,7 +650,7 @@ pymain_run_file(_PyCoreConfig *config, PyCompilerFlags *cf)
 static void
 pymain_run_startup(_PyCoreConfig *config, PyCompilerFlags *cf)
 {
-    const char *startup = _Py_GetEnv(config->preconfig.use_environment, "PYTHONSTARTUP");
+    const char *startup = _Py_GetEnv(config->use_environment, "PYTHONSTARTUP");
     if (startup == NULL) {
         return;
     }
@@ -735,7 +730,7 @@ pymain_repl(_PyCoreConfig *config, PyCompilerFlags *cf, int *exitcode)
 {
     /* Check this environment variable at the end, to give programs the
        opportunity to set it from Python. */
-    if (!Py_InspectFlag && _Py_GetEnv(config->preconfig.use_environment, "PYTHONINSPECT")) {
+    if (!Py_InspectFlag && _Py_GetEnv(config->use_environment, "PYTHONINSPECT")) {
         Py_InspectFlag = 1;
         config->inspect = 1;
     }
@@ -775,7 +770,7 @@ pymain_run_python(PyInterpreterState *interp, int *exitcode)
             goto done;
         }
     }
-    else if (!config->preconfig.isolated) {
+    else if (!config->isolated) {
         PyObject *path0 = NULL;
         if (_PyPathConfig_ComputeSysPath0(&config->argv, &path0)) {
             if (path0 == NULL) {
index e6c51a4a1dfbe82cfa355ad5a1ecb6156d02998b..0818012d8c5abd4dbc7f379046e375ddfe4fc024 100644 (file)
@@ -77,7 +77,7 @@ main(int argc, char *argv[])
     text[text_size] = '\0';
 
     _PyCoreConfig config = _PyCoreConfig_INIT;
-    config.preconfig.use_environment = 0;
+    config.use_environment = 0;
     config.user_site_directory = 0;
     config.site_import = 0;
     config.program_name = L"./_freeze_importlib";
index ab5802da36303d36fb47158338d461e823dcffb9..70ef45f9281c6771ecb35038abba32687d6d16bc 100644 (file)
@@ -397,6 +397,22 @@ static int test_init_global_config(void)
 
 static int test_init_from_config(void)
 {
+    _PyInitError err;
+
+    _PyPreConfig preconfig = _PyPreConfig_INIT;
+
+    putenv("PYTHONMALLOC=malloc_debug");
+    preconfig.allocator = "malloc";
+
+    putenv("PYTHONUTF8=0");
+    Py_UTF8Mode = 0;
+    preconfig.utf8_mode = 1;
+
+    err = _Py_PreInitializeFromPreConfig(&preconfig);
+    if (_Py_INIT_FAILED(err)) {
+        _Py_ExitInitError(err);
+    }
+
     /* Test _Py_InitializeFromConfig() */
     _PyCoreConfig config = _PyCoreConfig_INIT;
     config.install_signal_handlers = 0;
@@ -407,9 +423,6 @@ static int test_init_from_config(void)
     config.use_hash_seed = 1;
     config.hash_seed = 123;
 
-    putenv("PYTHONMALLOC=malloc_debug");
-    config.preconfig.allocator = "malloc";
-
     /* dev_mode=1 is tested in test_init_dev_mode() */
 
     putenv("PYTHONFAULTHANDLER=");
@@ -430,10 +443,6 @@ static int test_init_from_config(void)
 
     /* FIXME: test coerce_c_locale and coerce_c_locale_warn */
 
-    putenv("PYTHONUTF8=0");
-    Py_UTF8Mode = 0;
-    config.preconfig.utf8_mode = 1;
-
     putenv("PYTHONPYCACHEPREFIX=env_pycache_prefix");
     config.pycache_prefix = L"conf_pycache_prefix";
 
@@ -521,7 +530,7 @@ static int test_init_from_config(void)
     Py_FrozenFlag = 0;
     config._frozen = 1;
 
-    _PyInitError err = _Py_InitializeFromConfig(&config);
+    err = _Py_InitializeFromConfig(&config);
     /* Don't call _PyCoreConfig_Clear() since all strings are static */
     if (_Py_INIT_FAILED(err)) {
         _Py_ExitInitError(err);
@@ -607,20 +616,30 @@ static int test_init_env_dev_mode_alloc(void)
 
 static int test_init_isolated(void)
 {
+    _PyInitError err;
+
+    _PyPreConfig preconfig = _PyPreConfig_INIT;
+
+    /* Set coerce_c_locale and utf8_mode to not depend on the locale */
+    preconfig.coerce_c_locale = 0;
+    preconfig.utf8_mode = 0;
+
+    err = _Py_PreInitializeFromPreConfig(&preconfig);
+    if (_Py_INIT_FAILED(err)) {
+        _Py_ExitInitError(err);
+    }
+
     /* Test _PyCoreConfig.isolated=1 */
     _PyCoreConfig config = _PyCoreConfig_INIT;
 
     Py_IsolatedFlag = 0;
-    config.preconfig.isolated = 1;
+    config.isolated = 1;
 
-    /* Set coerce_c_locale and utf8_mode to not depend on the locale */
-    config.preconfig.coerce_c_locale = 0;
-    config.preconfig.utf8_mode = 0;
     /* Use path starting with "./" avoids a search along the PATH */
     config.program_name = L"./_testembed";
 
     test_init_env_dev_mode_putenvs();
-    _PyInitError err = _Py_InitializeFromConfig(&config);
+    err = _Py_InitializeFromConfig(&config);
     if (_Py_INIT_FAILED(err)) {
         _Py_ExitInitError(err);
     }
@@ -635,7 +654,7 @@ static int test_init_dev_mode(void)
     _PyCoreConfig config = _PyCoreConfig_INIT;
     putenv("PYTHONFAULTHANDLER=");
     putenv("PYTHONMALLOC=");
-    config.preconfig.dev_mode = 1;
+    config.dev_mode = 1;
     config.program_name = L"./_testembed";
     _PyInitError err = _Py_InitializeFromConfig(&config);
     if (_Py_INIT_FAILED(err)) {
index 1245aef54b8749ee4909bdf14512c68d8d464484..2e6eb40298799dd77648bddf5796453d1d939ca1 100644 (file)
@@ -469,8 +469,6 @@ Py_GetArgcArgv(int *argc, wchar_t ***argv)
 void
 _PyCoreConfig_Clear(_PyCoreConfig *config)
 {
-    _PyPreConfig_Clear(&config->preconfig);
-
 #define CLEAR(ATTR) \
     do { \
         PyMem_RawFree(ATTR); \
@@ -514,10 +512,6 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
 {
     _PyCoreConfig_Clear(config);
 
-    if (_PyPreConfig_Copy(&config->preconfig, &config2->preconfig) < 0) {
-        return -1;
-    }
-
 #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR
 #define COPY_STR_ATTR(ATTR) \
     do { \
@@ -544,6 +538,9 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
         } \
     } while (0)
 
+    COPY_ATTR(isolated);
+    COPY_ATTR(use_environment);
+    COPY_ATTR(dev_mode);
     COPY_ATTR(install_signal_handlers);
     COPY_ATTR(use_hash_seed);
     COPY_ATTR(hash_seed);
@@ -613,7 +610,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
 static const char*
 _PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name)
 {
-    return _Py_GetEnv(config->preconfig.use_environment, name);
+    return _Py_GetEnv(config->use_environment, name);
 }
 
 
@@ -622,9 +619,9 @@ _PyCoreConfig_GetEnvDup(const _PyCoreConfig *config,
                         wchar_t **dest,
                         wchar_t *wname, char *name)
 {
-    assert(config->preconfig.use_environment >= 0);
+    assert(config->use_environment >= 0);
 
-    if (!config->preconfig.use_environment) {
+    if (!config->use_environment) {
         *dest = NULL;
         return 0;
     }
@@ -668,8 +665,6 @@ _PyCoreConfig_GetEnvDup(const _PyCoreConfig *config,
 void
 _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
 {
-    _PyPreConfig_GetGlobalConfig(&config->preconfig);
-
 #define COPY_FLAG(ATTR, VALUE) \
         if (config->ATTR == -1) { \
             config->ATTR = VALUE; \
@@ -679,6 +674,8 @@ _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
             config->ATTR = !(VALUE); \
         }
 
+    COPY_FLAG(isolated, Py_IsolatedFlag);
+    COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
     COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
     COPY_FLAG(inspect, Py_InspectFlag);
     COPY_FLAG(interactive, Py_InteractiveFlag);
@@ -714,6 +711,8 @@ _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
             VAR = !config->ATTR; \
         }
 
+    COPY_FLAG(isolated, Py_IsolatedFlag);
+    COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag);
     COPY_FLAG(bytes_warning, Py_BytesWarningFlag);
     COPY_FLAG(inspect, Py_InspectFlag);
     COPY_FLAG(interactive, Py_InteractiveFlag);
@@ -924,7 +923,7 @@ config_wstr_to_int(const wchar_t *wstr, int *result)
 static _PyInitError
 config_read_env_vars(_PyCoreConfig *config)
 {
-    int use_env = config->preconfig.use_environment;
+    int use_env = config->use_environment;
 
     /* Get environment variables */
     _Py_get_env_flag(use_env, &config->parser_debug, "PYTHONDEBUG");
@@ -1149,7 +1148,8 @@ get_locale_encoding(char **locale_encoding)
 
 
 static _PyInitError
-config_init_stdio_encoding(_PyCoreConfig *config)
+config_init_stdio_encoding(_PyCoreConfig *config,
+                           const _PyPreConfig *preconfig)
 {
     /* If Py_SetStandardStreamEncoding() have been called, use these
         parameters. */
@@ -1219,7 +1219,7 @@ config_init_stdio_encoding(_PyCoreConfig *config)
     }
 
     /* UTF-8 Mode uses UTF-8/surrogateescape */
-    if (config->preconfig.utf8_mode) {
+    if (preconfig->utf8_mode) {
         if (config->stdio_encoding == NULL) {
             config->stdio_encoding = _PyMem_RawStrdup("utf-8");
             if (config->stdio_encoding == NULL) {
@@ -1254,10 +1254,10 @@ config_init_stdio_encoding(_PyCoreConfig *config)
 
 
 static _PyInitError
-config_init_fs_encoding(_PyCoreConfig *config)
+config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig)
 {
 #ifdef MS_WINDOWS
-    if (config->preconfig.legacy_windows_fs_encoding) {
+    if (preconfig->legacy_windows_fs_encoding) {
         /* Legacy Windows filesystem encoding: mbcs/replace */
         if (config->filesystem_encoding == NULL) {
             config->filesystem_encoding = _PyMem_RawStrdup("mbcs");
@@ -1292,7 +1292,7 @@ config_init_fs_encoding(_PyCoreConfig *config)
     }
 #else
     if (config->filesystem_encoding == NULL) {
-        if (config->preconfig.utf8_mode) {
+        if (preconfig->utf8_mode) {
             /* UTF-8 Mode use: utf-8/surrogateescape */
             config->filesystem_encoding = _PyMem_RawStrdup("utf-8");
             /* errors defaults to surrogateescape above */
@@ -1341,12 +1341,8 @@ config_read_impl(_PyCoreConfig *config, _PyPreCmdline *cmdline)
 {
     _PyInitError err;
 
-    err = _Py_PreInitializeFromConfig(config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
-    }
-
-    _PyPreCmdline_GetPreConfig(cmdline, &_PyRuntime.preconfig);
+    const _PyPreConfig *preconfig = &_PyRuntime.preconfig;
+    _PyPreCmdline_GetPreConfig(cmdline, preconfig);
     _PyPreCmdline_GetCoreConfig(cmdline, config);
 
     err = _PyPreCmdline_Read(cmdline);
@@ -1360,19 +1356,16 @@ config_read_impl(_PyCoreConfig *config, _PyPreCmdline *cmdline)
         return _Py_INIT_NO_MEMORY();
     }
 
-    if (_PyPreConfig_Copy(&config->preconfig, &_PyRuntime.preconfig) < 0) {
-        return _Py_INIT_NO_MEMORY();
-    }
-
     _PyCoreConfig_GetGlobalConfig(config);
 
-    assert(config->preconfig.use_environment >= 0);
+    assert(config->use_environment >= 0);
 
-    if (config->preconfig.isolated > 0) {
+    if (config->isolated > 0) {
+        config->use_environment = 0;
         config->user_site_directory = 0;
     }
 
-    if (config->preconfig.use_environment) {
+    if (config->use_environment) {
         err = config_read_env_vars(config);
         if (_Py_INIT_FAILED(err)) {
             return err;
@@ -1421,7 +1414,7 @@ config_read_impl(_PyCoreConfig *config, _PyPreCmdline *cmdline)
     }
 
     /* default values */
-    if (config->preconfig.dev_mode) {
+    if (config->dev_mode) {
         if (config->faulthandler < 0) {
             config->faulthandler = 1;
         }
@@ -1438,13 +1431,13 @@ config_read_impl(_PyCoreConfig *config, _PyPreCmdline *cmdline)
     }
 
     if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) {
-        err = config_init_fs_encoding(config);
+        err = config_init_fs_encoding(config, preconfig);
         if (_Py_INIT_FAILED(err)) {
             return err;
         }
     }
 
-    err = config_init_stdio_encoding(config);
+    err = config_init_stdio_encoding(config, preconfig);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
@@ -1456,7 +1449,7 @@ config_read_impl(_PyCoreConfig *config, _PyPreCmdline *cmdline)
         }
     }
 
-    assert(config->preconfig.use_environment >= 0);
+    assert(config->use_environment >= 0);
     assert(config->filesystem_encoding != NULL);
     assert(config->filesystem_errors != NULL);
     assert(config->stdio_encoding != NULL);
@@ -1544,22 +1537,11 @@ config_init_stdio(const _PyCoreConfig *config)
 
    - set Py_xxx global configuration variables
    - initialize C standard streams (stdin, stdout, stderr) */
-_PyInitError
+void
 _PyCoreConfig_Write(const _PyCoreConfig *config)
 {
     _PyCoreConfig_SetGlobalConfig(config);
     config_init_stdio(config);
-
-    /* Write the new pre-configuration into _PyRuntime */
-    PyMemAllocatorEx old_alloc;
-    _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
-    int res = _PyPreConfig_Copy(&_PyRuntime.preconfig, &config->preconfig);
-    PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
-    if (res < 0) {
-        return _Py_INIT_NO_MEMORY();
-    }
-
-    return _Py_INIT_OK();
 }
 
 
@@ -1604,6 +1586,9 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
 #define SET_ITEM_WSTRLIST(LIST) \
     SET_ITEM(#LIST, _PyWstrList_AsList(&config->LIST))
 
+    SET_ITEM_INT(isolated);
+    SET_ITEM_INT(use_environment);
+    SET_ITEM_INT(dev_mode);
     SET_ITEM_INT(install_signal_handlers);
     SET_ITEM_INT(use_hash_seed);
     SET_ITEM_UINT(hash_seed);
@@ -1945,7 +1930,7 @@ config_init_warnoptions(_PyCoreConfig *config, const _PyCmdline *cmdline)
      * the lowest precedence entries first so that later entries override them.
      */
 
-    if (config->preconfig.dev_mode) {
+    if (config->dev_mode) {
         if (_PyWstrList_Append(&config->warnoptions, L"default")) {
             return _Py_INIT_NO_MEMORY();
         }
@@ -2101,7 +2086,7 @@ config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline)
         return err;
     }
 
-    if (config->preconfig.use_environment) {
+    if (config->use_environment) {
         err = cmdline_init_env_warnoptions(cmdline, config);
         if (_Py_INIT_FAILED(err)) {
             return err;
@@ -2178,8 +2163,7 @@ _Py_GetConfigsAsDict(void)
 
     /* pre config */
     PyInterpreterState *interp = _PyInterpreterState_Get();
-    const _PyCoreConfig *core_config = _PyInterpreterState_GetCoreConfig(interp);
-    const _PyPreConfig *pre_config = &core_config->preconfig;
+    const _PyPreConfig *pre_config = &_PyRuntime.preconfig;
     dict = _PyPreConfig_AsDict(pre_config);
     if (dict == NULL) {
         goto error;
@@ -2190,6 +2174,7 @@ _Py_GetConfigsAsDict(void)
     Py_CLEAR(dict);
 
     /* core config */
+    const _PyCoreConfig *core_config = _PyInterpreterState_GetCoreConfig(interp);
     dict = _PyCoreConfig_AsDict(core_config);
     if (dict == NULL) {
         goto error;
index f0b13fd1b00165a2b20b31b707164d454732029b..7fea7c3667865c45e6488b630824cbd0b46d8dcc 100644 (file)
@@ -331,7 +331,7 @@ _PyCoreConfig_CalculatePathConfig(_PyCoreConfig *config)
 #endif
 
     if (path_config.isolated != -1) {
-        config->preconfig.isolated = path_config.isolated;
+        config->isolated = path_config.isolated;
     }
     if (path_config.site_import != -1) {
         config->site_import = path_config.site_import;
index 8b685ce42d044ee7265ec598968b82dbdf584c34..d336352d93c2c2196e5dd93c5062b90e3c94f4e3 100644 (file)
@@ -143,6 +143,23 @@ _PyPreCmdline_GetPreConfig(_PyPreCmdline *cmdline, const _PyPreConfig *config)
 
     COPY_ATTR(use_environment);
     COPY_ATTR(isolated);
+    COPY_ATTR(dev_mode);
+
+#undef COPY_ATTR
+}
+
+
+void
+_PyPreCmdline_SetPreConfig(const _PyPreCmdline *cmdline, _PyPreConfig *config)
+{
+#define COPY_ATTR(ATTR) \
+    if (cmdline->ATTR != -1) { \
+        config->ATTR = cmdline->ATTR; \
+    }
+
+    COPY_ATTR(use_environment);
+    COPY_ATTR(isolated);
+    COPY_ATTR(dev_mode);
 
 #undef COPY_ATTR
 }
@@ -152,12 +169,13 @@ void
 _PyPreCmdline_GetCoreConfig(_PyPreCmdline *cmdline, const _PyCoreConfig *config)
 {
 #define COPY_ATTR(ATTR) \
-    if (config->preconfig.ATTR != -1) { \
-        cmdline->ATTR = config->preconfig.ATTR; \
+    if (config->ATTR != -1) { \
+        cmdline->ATTR = config->ATTR; \
     }
 
     COPY_ATTR(use_environment);
     COPY_ATTR(isolated);
+    COPY_ATTR(dev_mode);
 
 #undef COPY_ATTR
 }
@@ -167,12 +185,13 @@ void
 _PyPreCmdline_SetCoreConfig(const _PyPreCmdline *cmdline, _PyCoreConfig *config)
 {
 #define COPY_ATTR(ATTR) \
-    if (config->preconfig.ATTR == -1 && cmdline->ATTR != -1) { \
-        config->preconfig.ATTR = cmdline->ATTR; \
+    if (config->ATTR == -1 && cmdline->ATTR != -1) { \
+        config->ATTR = cmdline->ATTR; \
     }
 
     COPY_ATTR(use_environment);
     COPY_ATTR(isolated);
+    COPY_ATTR(dev_mode);
 
 #undef COPY_ATTR
 }
@@ -206,13 +225,13 @@ _PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2)
 
     COPY_ATTR(isolated);
     COPY_ATTR(use_environment);
+    COPY_ATTR(dev_mode);
     COPY_ATTR(coerce_c_locale);
     COPY_ATTR(coerce_c_locale_warn);
 #ifdef MS_WINDOWS
     COPY_ATTR(legacy_windows_fs_encoding);
 #endif
     COPY_ATTR(utf8_mode);
-    COPY_ATTR(dev_mode);
     COPY_STR_ATTR(allocator);
 
 #undef COPY_ATTR
@@ -567,21 +586,6 @@ get_ctype_locale(char **locale_p)
 }
 
 
-void
-_PyPreCmdline_SetPreConfig(const _PyPreCmdline *cmdline, _PyPreConfig *config)
-{
-#define COPY_ATTR(ATTR) \
-    if (cmdline->ATTR != -1) { \
-        config->ATTR = cmdline->ATTR; \
-    }
-
-    COPY_ATTR(use_environment);
-    COPY_ATTR(isolated);
-
-#undef COPY_ATTR
-}
-
-
 PyObject*
 _PyPreConfig_AsDict(const _PyPreConfig *config)
 {
@@ -712,7 +716,7 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args,
     if (coreconfig) {
         _PyPreCmdline_GetCoreConfig(&cmdline, coreconfig);
         if (config->dev_mode == -1) {
-            config->dev_mode = coreconfig->preconfig.dev_mode;
+            config->dev_mode = coreconfig->dev_mode;
         }
     }
 
index e08f290d8d14712e90486fdad26e84eea1154514..b12fa820e9cab7f42625080ab144e808b5b3743a 100644 (file)
@@ -286,9 +286,10 @@ static const char *_C_LOCALE_WARNING =
     "locales is recommended.\n";
 
 static void
-_emit_stderr_warning_for_legacy_locale(const _PyCoreConfig *core_config)
+_emit_stderr_warning_for_legacy_locale(void)
 {
-    if (core_config->preconfig.coerce_c_locale_warn && _Py_LegacyLocaleDetected()) {
+    const _PyPreConfig *preconfig = &_PyRuntime.preconfig;
+    if (preconfig->coerce_c_locale_warn && _Py_LegacyLocaleDetected()) {
         PySys_FormatStderr("%s", _C_LOCALE_WARNING);
     }
 }
@@ -675,6 +676,8 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p,
 {
     PyInterpreterState *interp;
 
+    _PyCoreConfig_Write(core_config);
+
     _PyInitError err = pycore_init_runtime(core_config);
     if (_Py_INIT_FAILED(err)) {
         return err;
@@ -720,54 +723,64 @@ pyinit_preinit(_PyPreConfig *config,
                const _PyCoreConfig *coreconfig)
 {
     _PyInitError err;
+    _PyPreConfig local_config = _PyPreConfig_INIT;
+    if (!config) {
+        config = &local_config;
+    }
 
     err = _PyRuntime_Initialize();
     if (_Py_INIT_FAILED(err)) {
-        return err;
+        goto done;
     }
 
     if (_PyRuntime.pre_initialized) {
         /* If it's already configured: ignored the new configuration */
-        return _Py_INIT_OK();
-    }
-
-    if (!src_config && coreconfig) {
-        src_config = &coreconfig->preconfig;
+        err = _Py_INIT_OK();
+        goto done;
     }
 
     if (src_config) {
         if (_PyPreConfig_Copy(config, src_config) < 0) {
-            return _Py_INIT_ERR("failed to copy pre config");
+            err = _Py_INIT_ERR("failed to copy pre config");
+            goto done;
         }
     }
 
     err = _PyPreConfig_Read(config, NULL, coreconfig);
     if (_Py_INIT_FAILED(err)) {
-        return err;
+        goto done;
     }
 
     err = _PyPreConfig_Write(config);
     if (_Py_INIT_FAILED(err)) {
-        return err;
+        goto done;
     }
 
     _PyRuntime.pre_initialized = 1;
-    return _Py_INIT_OK();
+    err = _Py_INIT_OK();
+
+done:
+    _PyPreConfig_Clear(&local_config);
+    return err;
 }
 
 
 _PyInitError
 _Py_PreInitialize(void)
 {
-    _PyPreConfig config = _PyPreConfig_INIT;
-    _PyInitError err = pyinit_preinit(&config, NULL, NULL);
-    _PyPreConfig_Clear(&config);
-    return err;
+    return pyinit_preinit(NULL, NULL, NULL);
 }
 
 
 _PyInitError
-_Py_PreInitializeFromPreConfig(_PyPreConfig *config)
+_Py_PreInitializeFromPreConfig(const _PyPreConfig *src_config)
+{
+    return pyinit_preinit(NULL, src_config, NULL);
+}
+
+
+_PyInitError
+_Py_PreInitializeInPlace(_PyPreConfig *config)
 {
     return pyinit_preinit(config, NULL, NULL);
 }
@@ -776,10 +789,7 @@ _Py_PreInitializeFromPreConfig(_PyPreConfig *config)
 _PyInitError
 _Py_PreInitializeFromConfig(const _PyCoreConfig *coreconfig)
 {
-    _PyPreConfig config = _PyPreConfig_INIT;
-    _PyInitError err = pyinit_preinit(&config, NULL, coreconfig);
-    _PyPreConfig_Clear(&config);
-    return err;
+    return pyinit_preinit(NULL, NULL, coreconfig);
 }
 
 
@@ -964,7 +974,7 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp,
     }
 
 #ifndef MS_WINDOWS
-    _emit_stderr_warning_for_legacy_locale(core_config);
+    _emit_stderr_warning_for_legacy_locale();
 #endif
 
     return _Py_INIT_OK();
index 3df4d44a7ce708de45d260997c87634a0aa9c6b9..12ec7d5918edea2bd5c89a38f0086a25f215ba3e 100644 (file)
@@ -2158,6 +2158,7 @@ make_flags(void)
 {
     int pos = 0;
     PyObject *seq;
+    const _PyPreConfig *preconfig = &_PyRuntime.preconfig;
     const _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config;
 
     seq = PyStructSequence_New(&FlagsType);
@@ -2174,16 +2175,16 @@ make_flags(void)
     SetFlag(!config->write_bytecode);
     SetFlag(!config->user_site_directory);
     SetFlag(!config->site_import);
-    SetFlag(!config->preconfig.use_environment);
+    SetFlag(!config->use_environment);
     SetFlag(config->verbose);
     /* SetFlag(saw_unbuffered_flag); */
     /* SetFlag(skipfirstline); */
     SetFlag(config->bytes_warning);
     SetFlag(config->quiet);
     SetFlag(config->use_hash_seed == 0 || config->hash_seed != 0);
-    SetFlag(config->preconfig.isolated);
-    PyStructSequence_SET_ITEM(seq, pos++, PyBool_FromLong(config->preconfig.dev_mode));
-    SetFlag(config->preconfig.utf8_mode);
+    SetFlag(config->isolated);
+    PyStructSequence_SET_ITEM(seq, pos++, PyBool_FromLong(config->dev_mode));
+    SetFlag(preconfig->utf8_mode);
 #undef SetFlag
 
     if (PyErr_Occurred()) {