[Python-checkins] bpo-32030: Complete _PyCoreConfig_Read() (#4946)

Victor Stinner webhook-mailer at python.org
Wed Dec 20 13:36:49 EST 2017


https://github.com/python/cpython/commit/9cfc00262c7f6b93072762eed1dc5d94fa3897f0
commit: 9cfc00262c7f6b93072762eed1dc5d94fa3897f0
branch: master
author: Victor Stinner <victor.stinner at gmail.com>
committer: GitHub <noreply at github.com>
date: 2017-12-20T19:36:46+01:00
summary:

bpo-32030: Complete _PyCoreConfig_Read() (#4946)

* Add _PyCoreConfig.install_signal_handlers
* Remove _PyMain.config: _PyMainInterpreterConfig usage is now
  restricted to pymain_init_python_main().
* Rename _PyMain.core_config to _PyMain.config
* _PyMainInterpreterConfig_Read() now creates the xoptions dictionary
   from the core config
* Fix _PyMainInterpreterConfig_Read(): don't replace xoptions and
  argv if they are already set.

files:
M Include/pystate.h
M Modules/main.c
M Python/pylifecycle.c

diff --git a/Include/pystate.h b/Include/pystate.h
index 619e627bf36..a4815286a74 100644
--- a/Include/pystate.h
+++ b/Include/pystate.h
@@ -25,6 +25,7 @@ typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int);
 
 
 typedef struct {
+    int install_signal_handlers;  /* Install signal handlers? -1 means unset */
     int ignore_environment; /* -E */
     int use_hash_seed;      /* PYTHONHASHSEED=x */
     unsigned long hash_seed;
@@ -62,6 +63,7 @@ typedef struct {
 
 #define _PyCoreConfig_INIT \
     (_PyCoreConfig){ \
+        .install_signal_handlers = -1, \
         .use_hash_seed = -1, \
         .coerce_c_locale = -1, \
         .utf8_mode = -1, \
@@ -73,7 +75,7 @@ typedef struct {
  * See PEP 432 for final anticipated contents
  */
 typedef struct {
-    int install_signal_handlers;
+    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 */
diff --git a/Modules/main.c b/Modules/main.c
index 385a09e2747..0a36f9db9d8 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -164,7 +164,7 @@ pymain_usage(int error, const wchar_t* program)
 
 
 static const char*
-pymain_get_env_var(const char *name)
+config_get_env_var(const char *name)
 {
     const char *var = Py_GETENV(name);
     if (var && var[0] != '\0') {
@@ -223,7 +223,7 @@ config_get_env_var_dup(wchar_t **dest, wchar_t *wname, char *name)
 static void
 pymain_run_startup(PyCompilerFlags *cf)
 {
-    const char *startup = pymain_get_env_var("PYTHONSTARTUP");
+    const char *startup = config_get_env_var("PYTHONSTARTUP");
     if (startup == NULL) {
         return;
     }
@@ -477,15 +477,13 @@ typedef struct {
     wchar_t *command;            /* -c argument */
     wchar_t *module;             /* -m argument */
 
-    _PyCoreConfig core_config;
-    _PyMainInterpreterConfig config;
+    _PyCoreConfig config;
 
     PyObject *main_importer_path;
 } _PyMain;
 
 #define _PyMain_INIT \
-    {.core_config = _PyCoreConfig_INIT, \
-     .config = _PyMainInterpreterConfig_INIT, \
+    {.config = _PyCoreConfig_INIT, \
      .err = _Py_INIT_OK()}
 /* Note: _PyMain_INIT sets other fields to 0/NULL */
 
@@ -559,8 +557,8 @@ pymain_init_cmdline_argv(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
     else {
         program = L"";
     }
-    pymain->core_config.program = pymain_wstrdup(pymain, program);
-    if (pymain->core_config.program == NULL) {
+    pymain->config.program = pymain_wstrdup(pymain, program);
+    if (pymain->config.program == NULL) {
         return -1;
     }
 
@@ -607,16 +605,14 @@ pymain_clear_pymain(_PyMain *pymain)
 }
 
 static void
-pymain_clear_configs(_PyMain *pymain)
+pymain_clear_config(_PyMain *pymain)
 {
-    _PyMainInterpreterConfig_Clear(&pymain->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(&pymain->core_config);
+    _PyCoreConfig_Clear(&pymain->config);
 
     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
 }
@@ -626,7 +622,6 @@ static void
 pymain_free_python(_PyMain *pymain)
 {
     Py_CLEAR(pymain->main_importer_path);
-    _PyMainInterpreterConfig_Clear(&pymain->config);
 
 #ifdef __INSURE__
     /* Insure++ is a memory analysis tool that aids in discovering
@@ -658,7 +653,7 @@ pymain_free_raw(_PyMain *pymain)
     PyMemAllocatorEx old_alloc;
     _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
 
-    _PyCoreConfig_Clear(&pymain->core_config);
+    _PyCoreConfig_Clear(&pymain->config);
     pymain_clear_pymain(pymain);
 
     clear_wstrlist(orig_argc, orig_argv);
@@ -702,24 +697,35 @@ pymain_run_main_from_importer(_PyMain *pymain)
 }
 
 
-static int
-pymain_wstrlist_append(_PyMain *pymain, int *len, wchar_t ***list, const wchar_t *str)
+static _PyInitError
+wstrlist_append(int *len, wchar_t ***list, const wchar_t *str)
 {
-    wchar_t *str2 = pymain_wstrdup(pymain, str);
+    wchar_t *str2 = _PyMem_RawWcsdup(str);
     if (str2 == NULL) {
-        return -1;
+        return _Py_INIT_NO_MEMORY();
     }
 
     size_t size = (*len + 1) * sizeof(list[0]);
     wchar_t **list2 = (wchar_t **)PyMem_RawRealloc(*list, size);
     if (list2 == NULL) {
         PyMem_RawFree(str2);
-        pymain->err = _Py_INIT_NO_MEMORY();
-        return -1;
+        return _Py_INIT_NO_MEMORY();
     }
     list2[*len] = str2;
     *list = list2;
     (*len)++;
+    return _Py_INIT_OK();
+}
+
+
+static int
+pymain_wstrlist_append(_PyMain *pymain, int *len, wchar_t ***list, const wchar_t *str)
+{
+    _PyInitError err = wstrlist_append(len, list, str);
+    if (_Py_INIT_FAILED(err)) {
+        pymain->err = err;
+        return -1;
+    }
     return 0;
 }
 
@@ -731,6 +737,8 @@ pymain_wstrlist_append(_PyMain *pymain, int *len, wchar_t ***list, const wchar_t
 static int
 pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
 {
+    _PyCoreConfig *config = &pymain->config;
+
     _PyOS_ResetGetOpt();
     do {
         int longindex = -1;
@@ -799,7 +807,7 @@ pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
             break;
 
         case 'I':
-            pymain->core_config.ignore_environment++;
+            config->ignore_environment++;
             cmdline->isolated++;
             cmdline->no_user_site_directory++;
             break;
@@ -823,7 +831,7 @@ pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
             break;
 
         case 'E':
-            pymain->core_config.ignore_environment++;
+            config->ignore_environment++;
             break;
 
         case 't':
@@ -862,8 +870,8 @@ pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
 
         case 'X':
             if (pymain_wstrlist_append(pymain,
-                                       &pymain->core_config.nxoption,
-                                       &pymain->core_config.xoptions,
+                                       &config->nxoption,
+                                       &config->xoptions,
                                        _PyOS_optarg) < 0) {
                 return -1;
             }
@@ -874,7 +882,7 @@ pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
             break;
 
         case 'R':
-            pymain->core_config.use_hash_seed = 0;
+            config->use_hash_seed = 0;
             break;
 
         /* This space reserved for other options */
@@ -903,7 +911,7 @@ pymain_parse_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
 
 
 static int
-pymain_add_xoption(PyObject *opts, const wchar_t *s)
+add_xoption(PyObject *opts, const wchar_t *s)
 {
     PyObject *name, *value;
 
@@ -933,48 +941,51 @@ pymain_add_xoption(PyObject *opts, const wchar_t *s)
     return -1;
 }
 
-static int
-pymain_init_xoptions_dict(_PyMain *pymain)
+
+static PyObject*
+config_create_xoptions_dict(const _PyCoreConfig *config)
 {
-    int nxoption = pymain->core_config.nxoption;
-    wchar_t **xoptions = pymain->core_config.xoptions;
+    int nxoption = config->nxoption;
+    wchar_t **xoptions = config->xoptions;
     PyObject *dict = PyDict_New();
     if (dict == NULL) {
-        return -1;
+        return NULL;
     }
 
     for (int i=0; i < nxoption; i++) {
         wchar_t *option = xoptions[i];
-        if (pymain_add_xoption(dict, option) < 0) {
+        if (add_xoption(dict, option) < 0) {
             Py_DECREF(dict);
-            return -1;
+            return NULL;
         }
     }
 
-    pymain->config.xoptions = dict;
-    return 0;
+    return dict;
 }
 
 
-static int
-pymain_add_warnings_optlist(_PyMain *pymain, int len, wchar_t **options)
+static _PyInitError
+config_add_warnings_optlist(_PyCoreConfig *config, int len, wchar_t **options)
 {
     for (int i = 0; i < len; i++) {
-        if (pymain_wstrlist_append(pymain,
-                                   &pymain->core_config.nwarnoption,
-                                   &pymain->core_config.warnoptions,
-                                   options[i]) < 0)
-        {
-            return -1;
+        _PyInitError err = wstrlist_append(&config->nwarnoption,
+                                           &config->warnoptions,
+                                           options[i]);
+        if (_Py_INIT_FAILED(err)) {
+            return err;
         }
     }
-    return 0;
+    return _Py_INIT_OK();
 }
 
 
-static int
-pymain_init_warnoptions(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
+static _PyInitError
+config_init_warnoptions(_PyCoreConfig *config, _Py_CommandLineDetails *cmdline)
 {
+    _PyInitError err;
+
+    assert(config->nwarnoption == 0);
+
     /* The priority order for warnings configuration is (highest precedence
      * first):
      *
@@ -990,22 +1001,27 @@ pymain_init_warnoptions(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
      * the lowest precedence entries first so that later entries override them.
      */
 
-    if (pymain->core_config.dev_mode) {
-        if (pymain_wstrlist_append(pymain,
-                                   &pymain->core_config.nwarnoption,
-                                   &pymain->core_config.warnoptions,
-                                   L"default") < 0)
-        {
-            return -1;
+    if (config->dev_mode) {
+        err = wstrlist_append(&config->nwarnoption,
+                              &config->warnoptions,
+                              L"default");
+        if (_Py_INIT_FAILED(err)) {
+            return err;
         }
     }
 
-    if (pymain_add_warnings_optlist(pymain, cmdline->nenv_warnoption, cmdline->env_warnoptions) < 0) {
-        return -1;
+    err = config_add_warnings_optlist(config,
+                                      cmdline->nenv_warnoption,
+                                      cmdline->env_warnoptions);
+    if (_Py_INIT_FAILED(err)) {
+        return err;
     }
 
-    if (pymain_add_warnings_optlist(pymain, cmdline->nwarnoption, cmdline->warnoptions) < 0) {
-        return -1;
+    err = config_add_warnings_optlist(config,
+                                      cmdline->nwarnoption,
+                                      cmdline->warnoptions);
+    if (_Py_INIT_FAILED(err)) {
+        return err;
     }
 
     /* If the bytes_warning_flag isn't set, bytesobject.c and bytearrayobject.c
@@ -1020,29 +1036,28 @@ pymain_init_warnoptions(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
         else {
             filter = L"default::BytesWarning";
         }
-        if (pymain_wstrlist_append(pymain,
-                                   &pymain->core_config.nwarnoption,
-                                   &pymain->core_config.warnoptions,
-                                   filter) < 0)
-        {
-            return -1;
+        err = wstrlist_append(&config->nwarnoption,
+                              &config->warnoptions,
+                              filter);
+        if (_Py_INIT_FAILED(err)) {
+            return err;
         }
     }
-    return 0;
+    return _Py_INIT_OK();
 }
 
 
 static int
-config_init_warnoptions(_PyMainInterpreterConfig *config,
-                        const _PyCoreConfig *core_config)
+main_config_init_warnoptions(_PyMainInterpreterConfig *main_config,
+                             const _PyCoreConfig *config)
 {
     PyObject *warnoptions = PyList_New(0);
     if (warnoptions == NULL) {
         return -1;
     }
 
-    for (int i = 0; i < core_config->nwarnoption; i++) {
-        PyObject *option = PyUnicode_FromWideChar(core_config->warnoptions[i], -1);
+    for (int i = 0; i < config->nwarnoption; i++) {
+        PyObject *option = PyUnicode_FromWideChar(config->warnoptions[i], -1);
         if (option == NULL) {
             goto error;
         }
@@ -1053,7 +1068,7 @@ config_init_warnoptions(_PyMainInterpreterConfig *config,
         Py_DECREF(option);
     }
 
-    config->warnoptions = warnoptions;
+    main_config->warnoptions = warnoptions;
     return 0;
 
 error:
@@ -1065,22 +1080,21 @@ config_init_warnoptions(_PyMainInterpreterConfig *config,
 /* Get warning options from PYTHONWARNINGS environment variable.
    Return 0 on success.
    Set pymain->err and return -1 on error. */
-static int
-pymain_warnings_envvar(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
+static _PyInitError
+cmdline_init_env_warnoptions(_Py_CommandLineDetails *cmdline)
 {
     if (Py_IgnoreEnvironmentFlag) {
-        return 0;
+        return _Py_INIT_OK();
     }
 
     wchar_t *env;
     int res = config_get_env_var_dup(&env, L"PYTHONWARNINGS", "PYTHONWARNINGS");
     if (res < 0) {
-        pymain->err = DECODE_LOCALE_ERR("PYTHONWARNINGS", res);
-        return -1;
+        return DECODE_LOCALE_ERR("PYTHONWARNINGS", res);
     }
 
     if (env == NULL) {
-        return 0;
+        return _Py_INIT_OK();
     }
 
 
@@ -1089,17 +1103,16 @@ pymain_warnings_envvar(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
          warning != NULL;
          warning = WCSTOK(NULL, L",", &context))
     {
-        if (pymain_wstrlist_append(pymain,
-                                   &cmdline->nenv_warnoption,
-                                   &cmdline->env_warnoptions,
-                                   warning) < 0)
-        {
+        _PyInitError err = wstrlist_append(&cmdline->nenv_warnoption,
+                                           &cmdline->env_warnoptions,
+                                          warning);
+        if (_Py_INIT_FAILED(err)) {
             PyMem_RawFree(env);
-            return -1;
+            return err;
         }
     }
     PyMem_RawFree(env);
-    return 0;
+    return _Py_INIT_OK();
 }
 
 
@@ -1170,7 +1183,7 @@ config_init_program_name(_PyCoreConfig *config)
        so the actual executable path is passed in an environment variable.
        See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
        script. */
-    const char *p = pymain_get_env_var("PYTHONEXECUTABLE");
+    const char *p = config_get_env_var("PYTHONEXECUTABLE");
     if (p != NULL) {
         size_t len;
         wchar_t* program_name = Py_DecodeLocale(p, &len);
@@ -1304,23 +1317,22 @@ pymain_init_core_argv(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
         argv[0] = arg0;
     }
 
-    pymain->core_config.argc = argc;
-    pymain->core_config.argv = argv;
+    pymain->config.argc = argc;
+    pymain->config.argv = argv;
     return 0;
 }
 
 
 static int
-config_init_argv(_PyMainInterpreterConfig *config, const _PyCoreConfig *core_config)
+main_config_init_argv(_PyMainInterpreterConfig *main_config,
+                      const _PyCoreConfig *config)
 {
-    assert(config->argv == NULL);
-
-    if (core_config->argc < 0) {
+    if (config->argc < 0) {
         return 0;
     }
 
-    int argc = core_config->argc;
-    wchar_t** argv = core_config->argv;
+    int argc = config->argc;
+    wchar_t** argv = config->argv;
     assert(argc >= 1 && argv != NULL);
 
     PyObject *list = PyList_New(argc);
@@ -1337,13 +1349,13 @@ config_init_argv(_PyMainInterpreterConfig *config, const _PyCoreConfig *core_con
         PyList_SET_ITEM(list, i, v);
     }
 
-    config->argv = list;
+    main_config->argv = list;
     return 0;
 }
 
 
 static int
-pymain_init_path0(_PyMain *pymain, PyObject **path0)
+pymain_compute_path0(_PyMain *pymain, PyObject **path0)
 {
     if (pymain->main_importer_path != NULL) {
         /* Let pymain_run_main_from_importer() adjust sys.path[0] later */
@@ -1356,8 +1368,8 @@ pymain_init_path0(_PyMain *pymain, PyObject **path0)
         return 0;
     }
 
-    *path0 = _PyPathConfig_ComputeArgv0(pymain->core_config.argc,
-                                        pymain->core_config.argv);
+    *path0 = _PyPathConfig_ComputeArgv0(pymain->config.argc,
+                                        pymain->config.argv);
     if (*path0 == NULL) {
         pymain->err = _Py_INIT_NO_MEMORY();
         return -1;
@@ -1408,8 +1420,8 @@ pymain_get_global_config(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
 #endif
     cmdline->check_hash_pycs_mode = _Py_CheckHashBasedPycsMode ;
 
-    pymain->core_config.ignore_environment = Py_IgnoreEnvironmentFlag;
-    pymain->core_config.utf8_mode = Py_UTF8Mode;
+    pymain->config.ignore_environment = Py_IgnoreEnvironmentFlag;
+    pymain->config.utf8_mode = Py_UTF8Mode;
 }
 
 
@@ -1435,12 +1447,12 @@ pymain_set_global_config(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
     Py_LegacyWindowsStdioFlag = cmdline->legacy_windows_stdio;
 #endif
 
-    Py_IgnoreEnvironmentFlag = pymain->core_config.ignore_environment;
-    Py_UTF8Mode = pymain->core_config.utf8_mode;
+    Py_IgnoreEnvironmentFlag = pymain->config.ignore_environment;
+    Py_UTF8Mode = pymain->config.utf8_mode;
 
     /* Random or non-zero hash seed */
-    Py_HashRandomizationFlag = (pymain->core_config.use_hash_seed == 0 ||
-                                pymain->core_config.hash_seed != 0);
+    Py_HashRandomizationFlag = (pymain->config.use_hash_seed == 0 ||
+                                pymain->config.hash_seed != 0);
 }
 
 
@@ -1483,7 +1495,7 @@ pymain_open_filename(_PyMain *pymain)
         else
             cfilename = "<unprintable file name>";
         fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n",
-                pymain->core_config.program, cfilename, err, strerror(err));
+                pymain->config.program, cfilename, err, strerror(err));
         PyMem_Free(cfilename_buffer);
         pymain->status = 2;
         return NULL;
@@ -1506,7 +1518,7 @@ pymain_open_filename(_PyMain *pymain)
             S_ISDIR(sb.st_mode)) {
         fprintf(stderr,
                 "%ls: '%ls' is a directory, cannot continue\n",
-                pymain->core_config.program, pymain->filename);
+                pymain->config.program, pymain->filename);
         fclose(fp);
         pymain->status = 1;
         return NULL;
@@ -1550,7 +1562,7 @@ pymain_repl(_PyMain *pymain, PyCompilerFlags *cf)
 {
     /* Check this environment variable at the end, to give programs the
        opportunity to set it from Python. */
-    if (!Py_InspectFlag && pymain_get_env_var("PYTHONINSPECT")) {
+    if (!Py_InspectFlag && config_get_env_var("PYTHONINSPECT")) {
         Py_InspectFlag = 1;
     }
 
@@ -1580,7 +1592,7 @@ pymain_parse_cmdline(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
         return -1;
     }
     if (res) {
-        pymain_usage(1, pymain->core_config.program);
+        pymain_usage(1, pymain->config.program);
         pymain->status = 2;
         return 1;
     }
@@ -1595,10 +1607,10 @@ pymain_parse_cmdline(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
 
 
 static const wchar_t*
-pymain_get_xoption(_PyMain *pymain, wchar_t *name)
+config_get_xoption(_PyCoreConfig *config, wchar_t *name)
 {
-    int nxoption = pymain->core_config.nxoption;
-    wchar_t **xoptions = pymain->core_config.xoptions;
+    int nxoption = config->nxoption;
+    wchar_t **xoptions = config->xoptions;
     for (int i=0; i < nxoption; i++) {
         wchar_t *option = xoptions[i];
         size_t len;
@@ -1653,13 +1665,13 @@ pymain_wstr_to_int(const wchar_t *wstr, int *result)
 }
 
 
-static int
-pymain_init_tracemalloc(_PyMain *pymain)
+static _PyInitError
+pymain_init_tracemalloc(_PyCoreConfig *config)
 {
     int nframe;
     int valid;
 
-    const char *env = pymain_get_env_var("PYTHONTRACEMALLOC");
+    const char *env = config_get_env_var("PYTHONTRACEMALLOC");
     if (env) {
         if (!pymain_str_to_int(env, &nframe)) {
             valid = (nframe >= 1);
@@ -1668,14 +1680,13 @@ pymain_init_tracemalloc(_PyMain *pymain)
             valid = 0;
         }
         if (!valid) {
-            pymain->err = _Py_INIT_USER_ERR("PYTHONTRACEMALLOC: invalid "
-                                            "number of frames");
-            return -1;
+            return _Py_INIT_USER_ERR("PYTHONTRACEMALLOC: invalid number "
+                                     "of frames");
         }
-        pymain->core_config.tracemalloc = nframe;
+        config->tracemalloc = nframe;
     }
 
-    const wchar_t *xoption = pymain_get_xoption(pymain, L"tracemalloc");
+    const wchar_t *xoption = config_get_xoption(config, L"tracemalloc");
     if (xoption) {
         const wchar_t *sep = wcschr(xoption, L'=');
         if (sep) {
@@ -1686,25 +1697,24 @@ pymain_init_tracemalloc(_PyMain *pymain)
                 valid = 0;
             }
             if (!valid) {
-                pymain->err = _Py_INIT_USER_ERR("-X tracemalloc=NFRAME: "
-                                                "invalid number of frames");
-                return -1;
+                return _Py_INIT_USER_ERR("-X tracemalloc=NFRAME: "
+                                         "invalid number of frames");
             }
         }
         else {
             /* -X tracemalloc behaves as -X tracemalloc=1 */
             nframe = 1;
         }
-        pymain->core_config.tracemalloc = nframe;
+        config->tracemalloc = nframe;
     }
-    return 0;
+    return _Py_INIT_OK();
 }
 
 
 static void
-pymain_get_env_flag(int *flag, const char *name)
+get_env_flag(int *flag, const char *name)
 {
-    const char *var = pymain_get_env_var(name);
+    const char *var = config_get_env_var(name);
     if (!var) {
         return;
     }
@@ -1720,44 +1730,24 @@ pymain_get_env_flag(int *flag, const char *name)
 
 
 static void
-pymain_get_env_flags(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
-{
-    pymain_get_env_flag(&cmdline->debug,
-                             "PYTHONDEBUG");
-    pymain_get_env_flag(&cmdline->verbosity,
-                             "PYTHONVERBOSE");
-    pymain_get_env_flag(&cmdline->optimization_level,
-                             "PYTHONOPTIMIZE");
-    pymain_get_env_flag(&cmdline->inspect,
-                             "PYTHONINSPECT");
-    pymain_get_env_flag(&cmdline->dont_write_bytecode,
-                             "PYTHONDONTWRITEBYTECODE");
-    pymain_get_env_flag(&cmdline->no_user_site_directory,
-                             "PYTHONNOUSERSITE");
-    pymain_get_env_flag(&cmdline->use_unbuffered_io,
-                             "PYTHONUNBUFFERED");
+cmdline_get_env_flags(_Py_CommandLineDetails *cmdline)
+{
+    get_env_flag(&cmdline->debug, "PYTHONDEBUG");
+    get_env_flag(&cmdline->verbosity, "PYTHONVERBOSE");
+    get_env_flag(&cmdline->optimization_level, "PYTHONOPTIMIZE");
+    get_env_flag(&cmdline->inspect, "PYTHONINSPECT");
+    get_env_flag(&cmdline->dont_write_bytecode, "PYTHONDONTWRITEBYTECODE");
+    get_env_flag(&cmdline->no_user_site_directory, "PYTHONNOUSERSITE");
+    get_env_flag(&cmdline->use_unbuffered_io, "PYTHONUNBUFFERED");
 #ifdef MS_WINDOWS
-    pymain_get_env_flag(&cmdline->legacy_windows_fs_encoding,
-                             "PYTHONLEGACYWINDOWSFSENCODING");
-    pymain_get_env_flag(&cmdline->legacy_windows_stdio,
-                             "PYTHONLEGACYWINDOWSSTDIO");
+    get_env_flag(&cmdline->legacy_windows_fs_encoding,
+                 "PYTHONLEGACYWINDOWSFSENCODING");
+    get_env_flag(&cmdline->legacy_windows_stdio,
+                 "PYTHONLEGACYWINDOWSSTDIO");
 #endif
 }
 
 
-static _PyInitError
-config_init_module_search_path_env(_PyCoreConfig *config)
-{
-    wchar_t *path;
-    int res = config_get_env_var_dup(&path, L"PYTHONPATH", "PYTHONPATH");
-    if (res < 0) {
-        return DECODE_LOCALE_ERR("PYTHONHOME", res);
-    }
-    config->module_search_path_env = path;
-    return _Py_INIT_OK();
-}
-
-
 static _PyInitError
 config_init_home(_PyCoreConfig *config)
 {
@@ -1786,7 +1776,7 @@ static _PyInitError
 config_init_hash_seed(_PyCoreConfig *config)
 {
     if (config->use_hash_seed < 0) {
-        const char *seed_text = pymain_get_env_var("PYTHONHASHSEED");
+        const char *seed_text = config_get_env_var("PYTHONHASHSEED");
         int use_hash_seed;
         unsigned long hash_seed;
         if (_Py_ReadHashSeed(seed_text, &use_hash_seed, &hash_seed) < 0) {
@@ -1800,121 +1790,121 @@ config_init_hash_seed(_PyCoreConfig *config)
 }
 
 
-static int
-pymain_init_utf8_mode(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
+static _PyInitError
+config_init_utf8_mode(_PyCoreConfig *config)
 {
-    _PyCoreConfig *core_config = &pymain->core_config;
-
-#ifdef MS_WINDOWS
-    if (cmdline->legacy_windows_fs_encoding) {
-        core_config->utf8_mode = 0;
-        return 0;
+    /* The option was already set by Py_UTF8Mode,
+       Py_LegacyWindowsFSEncodingFlag or PYTHONLEGACYWINDOWSFSENCODING. */
+    if (config->utf8_mode >= 0) {
+        return _Py_INIT_OK();
     }
-#endif
 
-    const wchar_t *xopt = pymain_get_xoption(pymain, L"utf8");
+    const wchar_t *xopt = config_get_xoption(config, L"utf8");
     if (xopt) {
         wchar_t *sep = wcschr(xopt, L'=');
         if (sep) {
             xopt = sep + 1;
             if (wcscmp(xopt, L"1") == 0) {
-                core_config->utf8_mode = 1;
+                config->utf8_mode = 1;
             }
             else if (wcscmp(xopt, L"0") == 0) {
-                core_config->utf8_mode = 0;
+                config->utf8_mode = 0;
             }
             else {
-                pymain->err = _Py_INIT_USER_ERR("invalid -X utf8 option value");
-                return -1;
+                return _Py_INIT_USER_ERR("invalid -X utf8 option value");
             }
         }
         else {
-            core_config->utf8_mode = 1;
+            config->utf8_mode = 1;
         }
-        return 0;
+        return _Py_INIT_OK();
     }
 
-    const char *opt = pymain_get_env_var("PYTHONUTF8");
+    const char *opt = config_get_env_var("PYTHONUTF8");
     if (opt) {
         if (strcmp(opt, "1") == 0) {
-            core_config->utf8_mode = 1;
+            config->utf8_mode = 1;
         }
         else if (strcmp(opt, "0") == 0) {
-            core_config->utf8_mode = 0;
+            config->utf8_mode = 0;
         }
         else {
-            pymain->err = _Py_INIT_USER_ERR("invalid PYTHONUTF8 environment "
-                                             "variable value");
-            return -1;
+            return _Py_INIT_USER_ERR("invalid PYTHONUTF8 environment "
+                                     "variable value");
         }
-        return 0;
+        return _Py_INIT_OK();
     }
-    return 0;
+
+    return _Py_INIT_OK();
 }
 
 
-static int
-pymain_parse_envvars(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
+static _PyInitError
+config_read_env_vars(_PyCoreConfig *config)
 {
-    _PyCoreConfig *core_config = &pymain->core_config;
-
-    /* Get environment variables */
-    pymain_get_env_flags(pymain, cmdline);
-
-    if (pymain_warnings_envvar(pymain, cmdline) < 0) {
-        return -1;
-    }
-
-    core_config->allocator = pymain_get_env_var("PYTHONMALLOC");
-
-    /* -X options */
-    if (pymain_get_xoption(pymain, L"showrefcount")) {
-        core_config->show_ref_count = 1;
-    }
-    if (pymain_get_xoption(pymain, L"showalloccount")) {
-        core_config->show_alloc_count = 1;
-    }
+    config->allocator = config_get_env_var("PYTHONMALLOC");
 
-    /* More complex options: env var and/or -X option */
-    if (pymain_get_env_var("PYTHONFAULTHANDLER")
-       || pymain_get_xoption(pymain, L"faulthandler")) {
-        core_config->faulthandler = 1;
-    }
-    if (pymain_get_env_var("PYTHONPROFILEIMPORTTIME")
-       || pymain_get_xoption(pymain, L"importtime")) {
-        core_config->import_time = 1;
-    }
-    if (pymain_init_tracemalloc(pymain) < 0) {
-        return -1;
-    }
-    if (pymain_get_xoption(pymain, L"dev" ) ||
-        pymain_get_env_var("PYTHONDEVMODE"))
-    {
-        core_config->dev_mode = 1;
-        core_config->faulthandler = 1;
-        core_config->allocator = "debug";
-    }
-    if (pymain_get_env_var("PYTHONDUMPREFS")) {
-        pymain->core_config.dump_refs = 1;
+    if (config_get_env_var("PYTHONDUMPREFS")) {
+        config->dump_refs = 1;
     }
-    if (pymain_get_env_var("PYTHONMALLOCSTATS")) {
-        pymain->core_config.malloc_stats = 1;
+    if (config_get_env_var("PYTHONMALLOCSTATS")) {
+        config->malloc_stats = 1;
     }
 
-    const char* env = pymain_get_env_var("PYTHONCOERCECLOCALE");
+    const char *env = config_get_env_var("PYTHONCOERCECLOCALE");
     if (env) {
         if (strcmp(env, "0") == 0) {
-            pymain->core_config.coerce_c_locale = 0;
+            config->coerce_c_locale = 0;
         }
         else if (strcmp(env, "warn") == 0) {
-            pymain->core_config.coerce_c_locale_warn = 1;
+            config->coerce_c_locale_warn = 1;
         }
         else {
-            pymain->core_config.coerce_c_locale = 1;
+            config->coerce_c_locale = 1;
         }
     }
 
-    return 0;
+    wchar_t *path;
+    int res = config_get_env_var_dup(&path, L"PYTHONPATH", "PYTHONPATH");
+    if (res < 0) {
+        return DECODE_LOCALE_ERR("PYTHONHOME", res);
+    }
+    config->module_search_path_env = path;
+
+    _PyInitError err = config_init_hash_seed(config);
+    if (_Py_INIT_FAILED(err)) {
+        return err;
+    }
+
+    return _Py_INIT_OK();
+}
+
+
+static _PyInitError
+config_read_complex_options(_PyCoreConfig *config)
+{
+    /* More complex options configured by env var and -X option */
+    if (config_get_env_var("PYTHONFAULTHANDLER")
+       || config_get_xoption(config, L"faulthandler")) {
+        config->faulthandler = 1;
+    }
+    if (config_get_env_var("PYTHONPROFILEIMPORTTIME")
+       || config_get_xoption(config, L"importtime")) {
+        config->import_time = 1;
+    }
+    if (config_get_xoption(config, L"dev" ) ||
+        config_get_env_var("PYTHONDEVMODE"))
+    {
+        config->dev_mode = 1;
+        config->faulthandler = 1;
+        config->allocator = "debug";
+    }
+
+    _PyInitError err = pymain_init_tracemalloc(config);
+    if (_Py_INIT_FAILED(err)) {
+        return err;
+    }
+    return _Py_INIT_OK();
 }
 
 
@@ -1927,27 +1917,37 @@ pymain_parse_envvars(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
 static int
 pymain_read_conf_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
 {
+    _PyInitError err;
+
     int res = pymain_parse_cmdline(pymain, cmdline);
     if (res != 0) {
         return res;
     }
 
-    if (pymain_init_core_argv(pymain, cmdline) < 0) {
-        return -1;
-    }
-
     /* Set Py_IgnoreEnvironmentFlag for Py_GETENV() */
-    Py_IgnoreEnvironmentFlag = pymain->core_config.ignore_environment;
+    _PyCoreConfig *config = &pymain->config;
+    Py_IgnoreEnvironmentFlag = config->ignore_environment;
 
-    if (pymain_parse_envvars(pymain, cmdline) < 0) {
+    /* Get environment variables */
+    cmdline_get_env_flags(cmdline);
+
+    err = cmdline_init_env_warnoptions(cmdline);
+    if (_Py_INIT_FAILED(err)) {
+        pymain->err = err;
         return -1;
     }
 
-    if (pymain_init_utf8_mode(pymain, cmdline) < 0) {
+#ifdef MS_WINDOWS
+    if (cmdline->legacy_windows_fs_encoding) {
+        config->utf8_mode = 0;
+    }
+#endif
+
+    if (pymain_init_core_argv(pymain, cmdline) < 0) {
         return -1;
     }
 
-    _PyInitError err = _PyCoreConfig_Read(&pymain->core_config);
+    err = _PyCoreConfig_Read(config);
     if (_Py_INIT_FAILED(err)) {
         pymain->err = err;
         return -1;
@@ -1979,10 +1979,10 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
 
     int locale_coerced = 0;
     int loops = 0;
-    int init_ignore_env = pymain->core_config.ignore_environment;
+    int init_ignore_env = pymain->config.ignore_environment;
 
     while (1) {
-        int utf8_mode = pymain->core_config.utf8_mode;
+        int utf8_mode = pymain->config.utf8_mode;
         int encoding_changed = 0;
 
         /* Watchdog to prevent an infinite loop */
@@ -1997,8 +1997,9 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
             goto done;
         }
 
-        res = pymain_read_conf_impl(pymain, cmdline);
-        if (res != 0) {
+        int conf_res = pymain_read_conf_impl(pymain, cmdline);
+        if (conf_res != 0) {
+            res = conf_res;
             goto done;
         }
 
@@ -2012,20 +2013,20 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
          * See the documentation of the PYTHONCOERCECLOCALE setting for more
          * details.
          */
-        if (pymain->core_config.coerce_c_locale == 1 && !locale_coerced) {
+        if (pymain->config.coerce_c_locale == 1 && !locale_coerced) {
             locale_coerced = 1;
-            _Py_CoerceLegacyLocale(&pymain->core_config);
+            _Py_CoerceLegacyLocale(&pymain->config);
             encoding_changed = 1;
         }
 
         if (utf8_mode == -1) {
-            if (pymain->core_config.utf8_mode == 1) {
+            if (pymain->config.utf8_mode == 1) {
                 /* UTF-8 Mode enabled */
                 encoding_changed = 1;
             }
         }
         else {
-            if (pymain->core_config.utf8_mode != utf8_mode) {
+            if (pymain->config.utf8_mode != utf8_mode) {
                 encoding_changed = 1;
             }
         }
@@ -2037,9 +2038,9 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
         /* Reset the configuration, except UTF-8 Mode. Set Py_UTF8Mode for
            Py_DecodeLocale(). Reset Py_IgnoreEnvironmentFlag, modified by
            pymain_read_conf_impl(). */
-        Py_UTF8Mode = pymain->core_config.utf8_mode;
+        Py_UTF8Mode = pymain->config.utf8_mode;
         Py_IgnoreEnvironmentFlag = init_ignore_env;
-        _PyCoreConfig_Clear(&pymain->core_config);
+        _PyCoreConfig_Clear(&pymain->config);
         pymain_clear_cmdline(pymain, cmdline);
         pymain_get_global_config(pymain, cmdline);
 
@@ -2059,6 +2060,34 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
 }
 
 
+static void
+config_init_locale(_PyCoreConfig *config)
+{
+    if (config->utf8_mode >= 0 && config->coerce_c_locale >= 0) {
+        return;
+    }
+
+    if (_Py_LegacyLocaleDetected()) {
+        /* POSIX locale: enable C locale coercion and UTF-8 Mode */
+        if (config->utf8_mode < 0) {
+            config->utf8_mode = 1;
+        }
+        if (config->coerce_c_locale < 0) {
+            config->coerce_c_locale = 1;
+        }
+        return;
+    }
+
+    /* By default, C locale coercion and UTF-8 Mode are disabled */
+    if (config->coerce_c_locale < 0) {
+        config->coerce_c_locale = 0;
+    }
+    if (config->utf8_mode < 0) {
+        config->utf8_mode = 0;
+    }
+}
+
+
 /* Read configuration settings from standard locations
  *
  * This function doesn't make any changes to the interpreter state - it
@@ -2074,42 +2103,46 @@ pymain_read_conf(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
 _PyInitError
 _PyCoreConfig_Read(_PyCoreConfig *config)
 {
-    _PyInitError err = config_init_home(config);
+    _PyInitError err;
+
+    err = config_read_env_vars(config);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
 
-    err = config_init_module_search_path_env(config);
+    /* -X options */
+    if (config_get_xoption(config, L"showrefcount")) {
+        config->show_ref_count = 1;
+    }
+    if (config_get_xoption(config, L"showalloccount")) {
+        config->show_alloc_count = 1;
+    }
+
+    err = config_read_complex_options(config);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
 
-    err = config_init_program_name(config);
+    err = config_init_utf8_mode(config);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
 
-    err = config_init_hash_seed(config);
+    err = config_init_home(config);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
 
-    if (config->utf8_mode < 0 || config->coerce_c_locale < 0) {
-        if (_Py_LegacyLocaleDetected()) {
-            if (config->utf8_mode < 0) {
-                config->utf8_mode = 1;
-            }
-            if (config->coerce_c_locale < 0) {
-                config->coerce_c_locale = 1;
-            }
-        }
+    err = config_init_program_name(config);
+    if (_Py_INIT_FAILED(err)) {
+        return err;
+    }
 
-        if (config->coerce_c_locale < 0) {
-            config->coerce_c_locale = 0;
-        }
-        if (config->utf8_mode < 0) {
-            config->utf8_mode = 0;
-        }
+    config_init_locale(config);
+
+    /* Signal handlers are installed by default */
+    if (config->install_signal_handlers < 0) {
+        config->install_signal_handlers = 1;
     }
 
     return _Py_INIT_OK();
@@ -2286,7 +2319,7 @@ _PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig *config,
 
 
 static PyObject *
-config_create_path_list(const wchar_t *path, wchar_t delim)
+create_path_list(const wchar_t *path, wchar_t delim)
 {
     int i, n;
     const wchar_t *p;
@@ -2323,105 +2356,104 @@ config_create_path_list(const wchar_t *path, wchar_t delim)
 
 
 _PyInitError
-_PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *config, const _PyCoreConfig *core_config)
+_PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config,
+                              const _PyCoreConfig *config)
 {
-    _PyInitError err = _PyPathConfig_Init(core_config);
+    _PyInitError err = _PyPathConfig_Init(config);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
 
-    if (config_init_argv(config, core_config) < 0) {
-        return _Py_INIT_ERR("failed to create sys.argv");
+    if (main_config->install_signal_handlers < 0) {
+        main_config->install_signal_handlers = config->install_signal_handlers;
     }
 
-    if (config_init_warnoptions(config, core_config) < 0) {
-        return _Py_INIT_NO_MEMORY();
+    if (main_config->xoptions == NULL) {
+        main_config->xoptions = config_create_xoptions_dict(config);
+        if (main_config->xoptions == NULL) {
+            return _Py_INIT_NO_MEMORY();
+        }
     }
 
-    /* Signal handlers are installed by default */
-    if (config->install_signal_handlers < 0) {
-        config->install_signal_handlers = 1;
+    if (main_config->argv == NULL) {
+        if (main_config_init_argv(main_config, config) < 0) {
+            return _Py_INIT_ERR("failed to create sys.argv");
+        }
     }
 
-    if (config->module_search_path == NULL &&
-        !core_config->_disable_importlib)
+    if (main_config->warnoptions == NULL) {
+        if (main_config_init_warnoptions(main_config, config) < 0) {
+            return _Py_INIT_NO_MEMORY();
+        }
+    }
 
+    if (main_config->module_search_path == NULL &&
+        !config->_disable_importlib)
     {
         wchar_t *sys_path = Py_GetPath();
-        config->module_search_path = config_create_path_list(sys_path, DELIM);
-        if (config->module_search_path == NULL) {
+        main_config->module_search_path = create_path_list(sys_path, DELIM);
+        if (main_config->module_search_path == NULL) {
             return _Py_INIT_NO_MEMORY();
         }
     }
 
-    if (config->executable == NULL) {
-        config->executable = PyUnicode_FromWideChar(Py_GetProgramFullPath(), -1);
-        if (config->executable == NULL) {
+    if (main_config->executable == NULL) {
+        main_config->executable = PyUnicode_FromWideChar(Py_GetProgramFullPath(), -1);
+        if (main_config->executable == NULL) {
             return _Py_INIT_NO_MEMORY();
         }
     }
 
-    if (config->prefix == NULL) {
-        config->prefix = PyUnicode_FromWideChar(Py_GetPrefix(), -1);
-        if (config->prefix == NULL) {
+    if (main_config->prefix == NULL) {
+        main_config->prefix = PyUnicode_FromWideChar(Py_GetPrefix(), -1);
+        if (main_config->prefix == NULL) {
             return _Py_INIT_NO_MEMORY();
         }
     }
 
-    if (config->exec_prefix == NULL) {
-        config->exec_prefix = PyUnicode_FromWideChar(Py_GetExecPrefix(), -1);
-        if (config->exec_prefix == NULL) {
+    if (main_config->exec_prefix == NULL) {
+        main_config->exec_prefix = PyUnicode_FromWideChar(Py_GetExecPrefix(), -1);
+        if (main_config->exec_prefix == NULL) {
             return _Py_INIT_NO_MEMORY();
         }
     }
 
-    if (config->base_prefix == NULL) {
-        Py_INCREF(config->prefix);
-        config->base_prefix = config->prefix;
+    if (main_config->base_prefix == NULL) {
+        Py_INCREF(main_config->prefix);
+        main_config->base_prefix = main_config->prefix;
     }
 
-    if (config->base_exec_prefix == NULL) {
-        Py_INCREF(config->exec_prefix);
-        config->base_exec_prefix = config->exec_prefix;
+    if (main_config->base_exec_prefix == NULL) {
+        Py_INCREF(main_config->exec_prefix);
+        main_config->base_exec_prefix = main_config->exec_prefix;
     }
     return _Py_INIT_OK();
 }
 
 
-static int
-pymain_init_python_core(_PyMain *pymain)
-{
-    pymain_init_stdio(pymain);
-
-    pymain->err = _Py_InitializeCore(&pymain->core_config);
-    if (_Py_INIT_FAILED(pymain->err)) {
-        return -1;
-    }
-    return 0;
-}
-
-
 static int
 pymain_init_python_main(_PyMain *pymain)
 {
-    if (pymain_init_xoptions_dict(pymain)) {
-        pymain->err = _Py_INIT_NO_MEMORY();
-        return -1;
-    }
+    _PyInitError err;
 
-    _PyInitError err = _PyMainInterpreterConfig_Read(&pymain->config,
-                                                     &pymain->core_config);
-    if (_Py_INIT_FAILED(err)) {
-        pymain->err = err;
-        return -1;
+    _PyMainInterpreterConfig main_config = _PyMainInterpreterConfig_INIT;
+    err = _PyMainInterpreterConfig_Read(&main_config, &pymain->config);
+    if (!_Py_INIT_FAILED(err)) {
+        err = _Py_InitializeMainInterpreter(&main_config);
     }
+    _PyMainInterpreterConfig_Clear(&main_config);
 
-    err = _Py_InitializeMainInterpreter(&pymain->config);
     if (_Py_INIT_FAILED(err)) {
         pymain->err = err;
         return -1;
     }
+    return 0;
+}
 
+
+static int
+pymain_init_sys_path(_PyMain *pymain)
+{
     if (pymain->filename != NULL) {
         /* If filename is a package (ex: directory or ZIP file) which contains
            __main__.py, main_importer_path is set to filename and will be
@@ -2431,11 +2463,11 @@ pymain_init_python_main(_PyMain *pymain)
     }
 
     PyObject *path0;
-    if (pymain_init_path0(pymain, &path0) < 0) {
+    if (pymain_compute_path0(pymain, &path0) < 0) {
         return -1;
     }
 
-    pymain_clear_configs(pymain);
+    pymain_clear_config(pymain);
 
     if (path0 != NULL) {
         if (pymain_update_sys_path(pymain, path0) < 0) {
@@ -2444,7 +2476,6 @@ pymain_init_python_main(_PyMain *pymain)
         }
         Py_DECREF(path0);
     }
-
     return 0;
 }
 
@@ -2466,6 +2497,7 @@ pymain_run_python(_PyMain *pymain)
     else {
         pymain_run_filename(pymain, &cf);
     }
+
     pymain_repl(pymain, &cf);
 }
 
@@ -2482,7 +2514,7 @@ pymain_init(_PyMain *pymain)
     fedisableexcept(FE_OVERFLOW);
 #endif
 
-    pymain->core_config._disable_importlib = 0;
+    pymain->config._disable_importlib = 0;
     pymain->config.install_signal_handlers = 1;
 }
 
@@ -2505,7 +2537,7 @@ pymain_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
     }
 
     if (cmdline->print_help) {
-        pymain_usage(0, pymain->core_config.program);
+        pymain_usage(0, pymain->config.program);
         return 1;
     }
 
@@ -2523,7 +2555,9 @@ pymain_cmdline_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
     }
     orig_argc = pymain->argc;
 
-    if (pymain_init_warnoptions(pymain, cmdline) < 0) {
+    _PyInitError err = config_init_warnoptions(&pymain->config, cmdline);
+    if (_Py_INIT_FAILED(err)) {
+        pymain->err = err;
         return -1;
     }
     return 0;
@@ -2571,7 +2605,10 @@ pymain_main(_PyMain *pymain)
         goto done;
     }
 
-    if (pymain_init_python_core(pymain) < 0) {
+    pymain_init_stdio(pymain);
+
+    pymain->err = _Py_InitializeCore(&pymain->config);
+    if (_Py_INIT_FAILED(pymain->err)) {
         _Py_FatalInitError(pymain->err);
     }
 
@@ -2579,6 +2616,10 @@ pymain_main(_PyMain *pymain)
         _Py_FatalInitError(pymain->err);
     }
 
+    if (pymain_init_sys_path(pymain) < 0) {
+        _Py_FatalInitError(pymain->err);
+    }
+
     pymain_run_python(pymain);
 
     if (Py_FinalizeEx() < 0) {
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 79fcb5777e3..2af76d76d2b 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -874,30 +874,29 @@ _Py_InitializeMainInterpreter(const _PyMainInterpreterConfig *config)
 _PyInitError
 _Py_InitializeEx_Private(int install_sigs, int install_importlib)
 {
-    _PyCoreConfig core_config = _PyCoreConfig_INIT;
-    _PyMainInterpreterConfig config = _PyMainInterpreterConfig_INIT;
+    _PyCoreConfig config = _PyCoreConfig_INIT;
     _PyInitError err;
 
-    core_config.ignore_environment = Py_IgnoreEnvironmentFlag;
-    core_config._disable_importlib = !install_importlib;
+    config.ignore_environment = Py_IgnoreEnvironmentFlag;
+    config._disable_importlib = !install_importlib;
     config.install_signal_handlers = install_sigs;
 
-    err = _PyCoreConfig_Read(&core_config);
+    err = _PyCoreConfig_Read(&config);
     if (_Py_INIT_FAILED(err)) {
         goto done;
     }
 
-    err = _Py_InitializeCore(&core_config);
+    err = _Py_InitializeCore(&config);
     if (_Py_INIT_FAILED(err)) {
         goto done;
     }
 
-    err = _PyMainInterpreterConfig_Read(&config, &core_config);
-    if (_Py_INIT_FAILED(err)) {
-        goto done;
+    _PyMainInterpreterConfig main_config = _PyMainInterpreterConfig_INIT;
+    err = _PyMainInterpreterConfig_Read(&main_config, &config);
+    if (!_Py_INIT_FAILED(err)) {
+        err = _Py_InitializeMainInterpreter(&main_config);
     }
-
-    err = _Py_InitializeMainInterpreter(&config);
+    _PyMainInterpreterConfig_Clear(&main_config);
     if (_Py_INIT_FAILED(err)) {
         goto done;
     }
@@ -905,8 +904,7 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
     err = _Py_INIT_OK();
 
 done:
-    _PyCoreConfig_Clear(&core_config);
-    _PyMainInterpreterConfig_Clear(&config);
+    _PyCoreConfig_Clear(&config);
     return err;
 }
 



More information about the Python-checkins mailing list