[Python-checkins] bpo-36444: Rework _Py_InitializeFromConfig() API (GH-12576)

Victor Stinner webhook-mailer at python.org
Wed Mar 27 08:40:21 EDT 2019


https://github.com/python/cpython/commit/5ac27a50ff2b42216746fedc0522a92c53089bb3
commit: 5ac27a50ff2b42216746fedc0522a92c53089bb3
branch: master
author: Victor Stinner <vstinner at redhat.com>
committer: GitHub <noreply at github.com>
date: 2019-03-27T13:40:14+01:00
summary:

bpo-36444: Rework _Py_InitializeFromConfig() API (GH-12576)

files:
M Include/cpython/coreconfig.h
M Include/cpython/pylifecycle.h
M Include/internal/pycore_coreconfig.h
M Include/internal/pycore_pylifecycle.h
M Modules/main.c
M Programs/_freeze_importlib.c
M Programs/_testembed.c
M Python/coreconfig.c
M Python/frozenmain.c
M Python/preconfig.c
M Python/pylifecycle.c

diff --git a/Include/cpython/coreconfig.h b/Include/cpython/coreconfig.h
index 53493ff85a37..27ee1f4c63fd 100644
--- a/Include/cpython/coreconfig.h
+++ b/Include/cpython/coreconfig.h
@@ -5,16 +5,6 @@
 extern "C" {
 #endif
 
-/* --- _PyArgv ---------------------------------------------------- */
-
-typedef struct {
-    int argc;
-    int use_bytes_argv;
-    char **bytes_argv;
-    wchar_t **wchar_argv;
-} _PyArgv;
-
-
 /* --- _PyInitError ----------------------------------------------- */
 
 typedef struct {
diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h
index 496dcb2c6043..e293b04e3f19 100644
--- a/Include/cpython/pylifecycle.h
+++ b/Include/cpython/pylifecycle.h
@@ -14,23 +14,33 @@ PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding,
 
 /* PEP 432 Multi-phase initialization API (Private while provisional!) */
 
-PyAPI_FUNC(_PyInitError) _Py_PreInitialize(void);
-PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromPreConfig(
-    const _PyPreConfig *preconfig);
-PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromConfig(
-    const _PyCoreConfig *coreconfig);
+PyAPI_FUNC(_PyInitError) _Py_PreInitialize(
+    const _PyPreConfig *src_config);
+PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromArgs(
+    const _PyPreConfig *src_config,
+    int argc,
+    char **argv);
+PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromWideArgs(
+    const _PyPreConfig *src_config,
+    int argc,
+    wchar_t **argv);
 
 PyAPI_FUNC(int) _Py_IsCoreInitialized(void);
 
 
-PyAPI_FUNC(_PyInitError) _Py_InitializeMainInterpreter(
-    PyInterpreterState *interp);
-
 /* Initialization and finalization */
 
 PyAPI_FUNC(_PyInitError) _Py_InitializeFromConfig(
+    const _PyCoreConfig *config);
+PyAPI_FUNC(_PyInitError) _Py_InitializeFromArgs(
+    const _PyCoreConfig *config,
+    int argc,
+    char **argv);
+PyAPI_FUNC(_PyInitError) _Py_InitializeFromWideArgs(
     const _PyCoreConfig *config,
-    PyInterpreterState **interp_p);
+    int argc,
+    wchar_t **argv);
+
 PyAPI_FUNC(void) _Py_NO_RETURN _Py_ExitInitError(_PyInitError err);
 
 /* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level
diff --git a/Include/internal/pycore_coreconfig.h b/Include/internal/pycore_coreconfig.h
index c5f39bac9f83..3a27628aa740 100644
--- a/Include/internal/pycore_coreconfig.h
+++ b/Include/internal/pycore_coreconfig.h
@@ -9,34 +9,6 @@ extern "C" {
 #endif
 
 
-/* --- _PyPreCmdline ------------------------------------------------- */
-
-typedef struct {
-    _PyWstrList argv;
-    _PyWstrList xoptions;     /* "-X value" option */
-    int isolated;             /* -I option */
-    int use_environment;      /* -E option */
-    int dev_mode;             /* -X dev and PYTHONDEVMODE */
-} _PyPreCmdline;
-
-#define _PyPreCmdline_INIT \
-    (_PyPreCmdline){ \
-        .use_environment = -1, \
-        .isolated = -1, \
-        .dev_mode = -1}
-/* Note: _PyPreCmdline_INIT sets other fields to 0/NULL */
-
-PyAPI_FUNC(void) _PyPreCmdline_Clear(_PyPreCmdline *cmdline);
-PyAPI_FUNC(_PyInitError) _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline,
-    const _PyArgv *args);
-PyAPI_FUNC(int) _PyPreCmdline_SetCoreConfig(
-    const _PyPreCmdline *cmdline,
-    _PyCoreConfig *config);
-PyAPI_FUNC(_PyInitError) _PyPreCmdline_Read(_PyPreCmdline *cmdline,
-    const _PyPreConfig *preconfig,
-    const _PyCoreConfig *coreconfig);
-
-
 /* --- _PyWstrList ------------------------------------------------ */
 
 #ifndef NDEBUG
@@ -54,15 +26,17 @@ PyAPI_FUNC(int) _PyWstrList_Extend(_PyWstrList *list,
 
 /* --- _PyArgv ---------------------------------------------------- */
 
+typedef struct {
+    int argc;
+    int use_bytes_argv;
+    char **bytes_argv;
+    wchar_t **wchar_argv;
+} _PyArgv;
+
 PyAPI_FUNC(_PyInitError) _PyArgv_AsWstrList(const _PyArgv *args,
     _PyWstrList *list);
 
 
-/* --- Py_GetArgcArgv() helpers ----------------------------------- */
-
-PyAPI_FUNC(void) _Py_ClearArgcArgv(void);
-
-
 /* --- Helper functions ------------------------------------------- */
 
 PyAPI_FUNC(int) _Py_str_to_int(
@@ -79,15 +53,47 @@ PyAPI_FUNC(void) _Py_get_env_flag(
     int *flag,
     const char *name);
 
+/* Py_GetArgcArgv() helper */
+PyAPI_FUNC(void) _Py_ClearArgcArgv(void);
+
+
+/* --- _PyPreCmdline ------------------------------------------------- */
+
+typedef struct {
+    _PyWstrList argv;
+    _PyWstrList xoptions;     /* "-X value" option */
+    int isolated;             /* -I option */
+    int use_environment;      /* -E option */
+    int dev_mode;             /* -X dev and PYTHONDEVMODE */
+} _PyPreCmdline;
+
+#define _PyPreCmdline_INIT \
+    (_PyPreCmdline){ \
+        .use_environment = -1, \
+        .isolated = -1, \
+        .dev_mode = -1}
+/* Note: _PyPreCmdline_INIT sets other fields to 0/NULL */
+
+PyAPI_FUNC(void) _PyPreCmdline_Clear(_PyPreCmdline *cmdline);
+PyAPI_FUNC(_PyInitError) _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline,
+    const _PyArgv *args);
+PyAPI_FUNC(int) _PyPreCmdline_SetCoreConfig(
+    const _PyPreCmdline *cmdline,
+    _PyCoreConfig *config);
+PyAPI_FUNC(_PyInitError) _PyPreCmdline_Read(_PyPreCmdline *cmdline,
+    const _PyPreConfig *preconfig);
+
+
 /* --- _PyPreConfig ----------------------------------------------- */
 
 PyAPI_FUNC(void) _PyPreConfig_Clear(_PyPreConfig *config);
 PyAPI_FUNC(int) _PyPreConfig_Copy(_PyPreConfig *config,
     const _PyPreConfig *config2);
 PyAPI_FUNC(PyObject*) _PyPreConfig_AsDict(const _PyPreConfig *config);
+PyAPI_FUNC(void) _PyCoreConfig_GetCoreConfig(_PyPreConfig *config,
+    const _PyCoreConfig *core_config);
 PyAPI_FUNC(_PyInitError) _PyPreConfig_Read(_PyPreConfig *config,
-    const _PyArgv *args,
-    const _PyCoreConfig *coreconfig);
+    const _PyArgv *args);
 PyAPI_FUNC(_PyInitError) _PyPreConfig_Write(_PyPreConfig *config);
 
 
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h
index 3214d6b06bd6..d837ea4fb33a 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -77,8 +77,8 @@ extern void _PyGILState_Fini(void);
 
 PyAPI_FUNC(void) _PyGC_DumpShutdownStats(void);
 
-PyAPI_FUNC(_PyInitError) _Py_PreInitializeInPlace(
-    _PyPreConfig *config);
+PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromCoreConfig(
+    const _PyCoreConfig *coreconfig);
 
 #ifdef __cplusplus
 }
diff --git a/Modules/main.c b/Modules/main.c
index 57d16093dcaa..ff79edbe43e0 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -34,27 +34,7 @@ extern "C" {
 /* --- pymain_init() ---------------------------------------------- */
 
 static _PyInitError
-pymain_init_preconfig(const _PyArgv *args)
-{
-    _PyInitError err;
-
-    _PyPreConfig config = _PyPreConfig_INIT;
-
-    err = _PyPreConfig_Read(&config, args, NULL);
-    if (_Py_INIT_FAILED(err)) {
-        goto done;
-    }
-
-    err = _Py_PreInitializeInPlace(&config);
-
-done:
-    _PyPreConfig_Clear(&config);
-    return err;
-}
-
-
-static _PyInitError
-pymain_init(const _PyArgv *args, PyInterpreterState **interp_p)
+pymain_init(const _PyArgv *args)
 {
     _PyInitError err;
 
@@ -72,28 +52,24 @@ pymain_init(const _PyArgv *args, PyInterpreterState **interp_p)
     fedisableexcept(FE_OVERFLOW);
 #endif
 
-    err = pymain_init_preconfig(args);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
-    }
-
     _PyCoreConfig config = _PyCoreConfig_INIT;
 
-    err = _PyCoreConfig_Read(&config, args);
-    if (_Py_INIT_FAILED(err)) {
-        goto done;
+    if (args->use_bytes_argv) {
+        err = _Py_PreInitializeFromArgs(NULL, args->argc, args->bytes_argv);
+    }
+    else {
+        err = _Py_PreInitializeFromWideArgs(NULL, args->argc, args->wchar_argv);
     }
-
-    err = _Py_InitializeFromConfig(&config, interp_p);
     if (_Py_INIT_FAILED(err)) {
-        goto done;
+        return err;
     }
 
-    err = _Py_INIT_OK();
-
-done:
-    _PyCoreConfig_Clear(&config);
-    return err;
+    if (args->use_bytes_argv) {
+        return _Py_InitializeFromArgs(&config, args->argc, args->bytes_argv);
+    }
+    else {
+        return _Py_InitializeFromWideArgs(&config, args->argc, args->wchar_argv);
+    }
 }
 
 
@@ -468,9 +444,12 @@ pymain_repl(_PyCoreConfig *config, PyCompilerFlags *cf, int *exitcode)
 
 
 static _PyInitError
-pymain_run_python(PyInterpreterState *interp, int *exitcode)
+pymain_run_python(int *exitcode)
 {
     _PyInitError err;
+
+    PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
+    /* pymain_run_stdin() modify the config */
     _PyCoreConfig *config = &interp->core_config;
 
     PyObject *main_importer_path = NULL;
@@ -586,14 +565,13 @@ pymain_main(_PyArgv *args)
 {
     _PyInitError err;
 
-    PyInterpreterState *interp;
-    err = pymain_init(args, &interp);
+    err = pymain_init(args);
     if (_Py_INIT_FAILED(err)) {
         goto exit_init_error;
     }
 
     int exitcode = 0;
-    err = pymain_run_python(interp, &exitcode);
+    err = pymain_run_python(&exitcode);
     if (_Py_INIT_FAILED(err)) {
         goto exit_init_error;
     }
diff --git a/Programs/_freeze_importlib.c b/Programs/_freeze_importlib.c
index 774748dc0915..6f77e86a9e66 100644
--- a/Programs/_freeze_importlib.c
+++ b/Programs/_freeze_importlib.c
@@ -86,7 +86,7 @@ main(int argc, char *argv[])
     config._frozen = 1;
     config._init_main = 0;
 
-    _PyInitError err = _Py_InitializeFromConfig(&config, NULL);
+    _PyInitError err = _Py_InitializeFromConfig(&config);
     /* 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 70587990f8de..425954cdd40b 100644
--- a/Programs/_testembed.c
+++ b/Programs/_testembed.c
@@ -408,7 +408,7 @@ static int test_init_from_config(void)
     Py_UTF8Mode = 0;
     preconfig.utf8_mode = 1;
 
-    err = _Py_PreInitializeFromPreConfig(&preconfig);
+    err = _Py_PreInitialize(&preconfig);
     if (_Py_INIT_FAILED(err)) {
         _Py_ExitInitError(err);
     }
@@ -529,7 +529,7 @@ static int test_init_from_config(void)
     Py_FrozenFlag = 0;
     config._frozen = 1;
 
-    err = _Py_InitializeFromConfig(&config, NULL);
+    err = _Py_InitializeFromConfig(&config);
     /* Don't call _PyCoreConfig_Clear() since all strings are static */
     if (_Py_INIT_FAILED(err)) {
         _Py_ExitInitError(err);
@@ -623,7 +623,7 @@ static int test_init_isolated(void)
     preconfig.coerce_c_locale = 0;
     preconfig.utf8_mode = 0;
 
-    err = _Py_PreInitializeFromPreConfig(&preconfig);
+    err = _Py_PreInitialize(&preconfig);
     if (_Py_INIT_FAILED(err)) {
         _Py_ExitInitError(err);
     }
@@ -638,7 +638,7 @@ static int test_init_isolated(void)
     config.program_name = L"./_testembed";
 
     test_init_env_dev_mode_putenvs();
-    err = _Py_InitializeFromConfig(&config, NULL);
+    err = _Py_InitializeFromConfig(&config);
     if (_Py_INIT_FAILED(err)) {
         _Py_ExitInitError(err);
     }
@@ -660,7 +660,7 @@ static int test_preinit_isolated1(void)
     preconfig.utf8_mode = 0;
     preconfig.isolated = 1;
 
-    err = _Py_PreInitializeFromPreConfig(&preconfig);
+    err = _Py_PreInitialize(&preconfig);
     if (_Py_INIT_FAILED(err)) {
         _Py_ExitInitError(err);
     }
@@ -669,7 +669,7 @@ static int test_preinit_isolated1(void)
     config.program_name = L"./_testembed";
 
     test_init_env_dev_mode_putenvs();
-    err = _Py_InitializeFromConfig(&config, NULL);
+    err = _Py_InitializeFromConfig(&config);
     if (_Py_INIT_FAILED(err)) {
         _Py_ExitInitError(err);
     }
@@ -691,7 +691,7 @@ static int test_preinit_isolated2(void)
     preconfig.utf8_mode = 0;
     preconfig.isolated = 0;
 
-    err = _Py_PreInitializeFromPreConfig(&preconfig);
+    err = _Py_PreInitialize(&preconfig);
     if (_Py_INIT_FAILED(err)) {
         _Py_ExitInitError(err);
     }
@@ -706,7 +706,7 @@ static int test_preinit_isolated2(void)
     config.program_name = L"./_testembed";
 
     test_init_env_dev_mode_putenvs();
-    err = _Py_InitializeFromConfig(&config, NULL);
+    err = _Py_InitializeFromConfig(&config);
     if (_Py_INIT_FAILED(err)) {
         _Py_ExitInitError(err);
     }
@@ -723,7 +723,7 @@ static int test_init_dev_mode(void)
     putenv("PYTHONMALLOC=");
     config.dev_mode = 1;
     config.program_name = L"./_testembed";
-    _PyInitError err = _Py_InitializeFromConfig(&config, NULL);
+    _PyInitError err = _Py_InitializeFromConfig(&config);
     if (_Py_INIT_FAILED(err)) {
         _Py_ExitInitError(err);
     }
diff --git a/Python/coreconfig.c b/Python/coreconfig.c
index ecb22e5667d7..13aa2272011f 100644
--- a/Python/coreconfig.c
+++ b/Python/coreconfig.c
@@ -1465,12 +1465,7 @@ static _PyInitError
 config_read(_PyCoreConfig *config, _PyPreCmdline *cmdline)
 {
     _PyInitError err;
-
     const _PyPreConfig *preconfig = &_PyRuntime.preconfig;
-    err = _PyPreCmdline_Read(cmdline, preconfig, config);
-    if (_Py_INIT_FAILED(err)) {
-        return err;
-    }
 
     if (_PyPreCmdline_SetCoreConfig(cmdline, config) < 0) {
         return _Py_INIT_NO_MEMORY();
@@ -2016,6 +2011,35 @@ config_usage(int error, const wchar_t* program)
 }
 
 
+static _PyInitError
+core_read_precmdline(_PyCoreConfig *config, const _PyArgv *args,
+                     _PyPreCmdline *precmdline)
+{
+    _PyInitError err;
+
+    if (args) {
+        err = _PyPreCmdline_SetArgv(precmdline, args);
+        if (_Py_INIT_FAILED(err)) {
+            return err;
+        }
+    }
+
+    _PyPreConfig preconfig = _PyPreConfig_INIT;
+    if (_PyPreConfig_Copy(&preconfig, &_PyRuntime.preconfig) < 0) {
+        err = _Py_INIT_NO_MEMORY();
+        goto done;
+    }
+
+    _PyCoreConfig_GetCoreConfig(&preconfig, config);
+
+    err = _PyPreCmdline_Read(precmdline, &preconfig);
+
+done:
+    _PyPreConfig_Clear(&preconfig);
+    return err;
+}
+
+
 /* Read the configuration into _PyCoreConfig from:
 
    * Command line arguments
@@ -2026,7 +2050,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config, const _PyArgv *args)
 {
     _PyInitError err;
 
-    err = _Py_PreInitializeFromConfig(config);
+    err = _Py_PreInitializeFromCoreConfig(config);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
@@ -2034,11 +2058,9 @@ _PyCoreConfig_Read(_PyCoreConfig *config, const _PyArgv *args)
     _PyCoreConfig_GetGlobalConfig(config);
 
     _PyPreCmdline precmdline = _PyPreCmdline_INIT;
-    if (args) {
-        err = _PyPreCmdline_SetArgv(&precmdline, args);
-        if (_Py_INIT_FAILED(err)) {
-            goto done;
-        }
+    err = core_read_precmdline(config, args, &precmdline);
+    if (_Py_INIT_FAILED(err)) {
+        goto done;
     }
 
     if (config->program == NULL) {
@@ -2048,12 +2070,6 @@ _PyCoreConfig_Read(_PyCoreConfig *config, const _PyArgv *args)
         }
     }
 
-    const _PyPreConfig *preconfig = &_PyRuntime.preconfig;
-    err = _PyPreCmdline_Read(&precmdline, preconfig, config);
-    if (_Py_INIT_FAILED(err)) {
-        goto done;
-    }
-
     _PyCmdline cmdline;
     memset(&cmdline, 0, sizeof(cmdline));
 
diff --git a/Python/frozenmain.c b/Python/frozenmain.c
index 041b4670ca38..6554aa75b038 100644
--- a/Python/frozenmain.c
+++ b/Python/frozenmain.c
@@ -82,7 +82,7 @@ Py_FrozenMain(int argc, char **argv)
     if (argc >= 1)
         Py_SetProgramName(argv_copy[0]);
 
-    err = _Py_InitializeFromConfig(&config, NULL);
+    err = _Py_InitializeFromConfig(&config);
     /* 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/preconfig.c b/Python/preconfig.c
index ce63ef0777aa..011ed53a8e73 100644
--- a/Python/preconfig.c
+++ b/Python/preconfig.c
@@ -148,22 +148,6 @@ _PyPreCmdline_SetPreConfig(const _PyPreCmdline *cmdline, _PyPreConfig *config)
 }
 
 
-static void
-_PyPreCmdline_GetCoreConfig(_PyPreCmdline *cmdline, const _PyCoreConfig *config)
-{
-#define COPY_ATTR(ATTR) \
-    if (config->ATTR != -1) { \
-        cmdline->ATTR = config->ATTR; \
-    }
-
-    COPY_ATTR(isolated);
-    COPY_ATTR(use_environment);
-    COPY_ATTR(dev_mode);
-
-#undef COPY_ATTR
-}
-
-
 int
 _PyPreCmdline_SetCoreConfig(const _PyPreCmdline *cmdline, _PyCoreConfig *config)
 {
@@ -231,17 +215,12 @@ precmdline_parse_cmdline(_PyPreCmdline *cmdline)
 
 _PyInitError
 _PyPreCmdline_Read(_PyPreCmdline *cmdline,
-                    const _PyPreConfig *preconfig,
-                    const _PyCoreConfig *coreconfig)
+                    const _PyPreConfig *preconfig)
 {
     if (preconfig) {
         _PyPreCmdline_GetPreConfig(cmdline, preconfig);
     }
 
-    if (coreconfig) {
-        _PyPreCmdline_GetCoreConfig(cmdline, coreconfig);
-    }
-
     _PyInitError err = precmdline_parse_cmdline(cmdline);
     if (_Py_INIT_FAILED(err)) {
         return err;
@@ -373,6 +352,23 @@ _PyPreConfig_AsDict(const _PyPreConfig *config)
 }
 
 
+void
+_PyCoreConfig_GetCoreConfig(_PyPreConfig *config,
+                            const _PyCoreConfig *core_config)
+{
+#define COPY_ATTR(ATTR) \
+    if (core_config->ATTR != -1) { \
+        config->ATTR = core_config->ATTR; \
+    }
+
+    COPY_ATTR(isolated);
+    COPY_ATTR(use_environment);
+    COPY_ATTR(dev_mode);
+
+#undef COPY_ATTR
+}
+
+
 static void
 _PyPreConfig_GetGlobalConfig(_PyPreConfig *config)
 {
@@ -640,12 +636,11 @@ preconfig_init_allocator(_PyPreConfig *config)
 
 
 static _PyInitError
-preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline,
-               const _PyCoreConfig *coreconfig)
+preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline)
 {
     _PyInitError err;
 
-    err = _PyPreCmdline_Read(cmdline, config, coreconfig);
+    err = _PyPreCmdline_Read(cmdline, config);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
@@ -692,8 +687,7 @@ preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline,
    - Py_xxx global configuration variables
    - the LC_CTYPE locale */
 _PyInitError
-_PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args,
-                  const _PyCoreConfig *coreconfig)
+_PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args)
 {
     _PyInitError err;
 
@@ -756,7 +750,7 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args,
         Py_LegacyWindowsFSEncodingFlag = config->legacy_windows_fs_encoding;
 #endif
 
-        err = preconfig_read(config, &cmdline, coreconfig);
+        err = preconfig_read(config, &cmdline);
         if (_Py_INIT_FAILED(err)) {
             goto done;
         }
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index f255fd9e132e..7c6948e6bdb1 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -718,40 +718,35 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p,
 
 
 static _PyInitError
-pyinit_preinit(_PyPreConfig *config,
-               const _PyPreConfig *src_config,
-               const _PyCoreConfig *coreconfig)
+preinit(const _PyPreConfig *src_config, const _PyArgv *args)
 {
     _PyInitError err;
-    _PyPreConfig local_config = _PyPreConfig_INIT;
-    if (!config) {
-        config = &local_config;
-    }
 
     err = _PyRuntime_Initialize();
     if (_Py_INIT_FAILED(err)) {
-        goto done;
+        return err;
     }
 
     if (_PyRuntime.pre_initialized) {
         /* If it's already configured: ignored the new configuration */
-        err = _Py_INIT_OK();
-        goto done;
+        return _Py_INIT_OK();
     }
 
+    _PyPreConfig config = _PyPreConfig_INIT;
+
     if (src_config) {
-        if (_PyPreConfig_Copy(config, src_config) < 0) {
-            err = _Py_INIT_ERR("failed to copy pre config");
+        if (_PyPreConfig_Copy(&config, src_config) < 0) {
+            err = _Py_INIT_NO_MEMORY();
             goto done;
         }
     }
 
-    err = _PyPreConfig_Read(config, NULL, coreconfig);
+    err = _PyPreConfig_Read(&config, args);
     if (_Py_INIT_FAILED(err)) {
         goto done;
     }
 
-    err = _PyPreConfig_Write(config);
+    err = _PyPreConfig_Write(&config);
     if (_Py_INIT_FAILED(err)) {
         goto done;
     }
@@ -760,48 +755,55 @@ pyinit_preinit(_PyPreConfig *config,
     err = _Py_INIT_OK();
 
 done:
-    _PyPreConfig_Clear(&local_config);
+    _PyPreConfig_Clear(&config);
     return err;
 }
 
-
 _PyInitError
-_Py_PreInitialize(void)
+_Py_PreInitializeFromArgs(const _PyPreConfig *src_config, int argc, char **argv)
 {
-    return pyinit_preinit(NULL, NULL, NULL);
+    _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv};
+    return preinit(src_config, &args);
 }
 
 
 _PyInitError
-_Py_PreInitializeFromPreConfig(const _PyPreConfig *src_config)
+_Py_PreInitializeFromWideArgs(const _PyPreConfig *src_config, int argc, wchar_t **argv)
 {
-    return pyinit_preinit(NULL, src_config, NULL);
+    _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv};
+    return preinit(src_config, &args);
 }
 
 
 _PyInitError
-_Py_PreInitializeInPlace(_PyPreConfig *config)
+_Py_PreInitialize(const _PyPreConfig *src_config)
 {
-    return pyinit_preinit(config, NULL, NULL);
+    return preinit(src_config, NULL);
 }
 
 
 _PyInitError
-_Py_PreInitializeFromConfig(const _PyCoreConfig *coreconfig)
+_Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig)
 {
-    return pyinit_preinit(NULL, NULL, coreconfig);
+    _PyPreConfig config = _PyPreConfig_INIT;
+    _PyCoreConfig_GetCoreConfig(&config, coreconfig);
+    return _Py_PreInitialize(&config);
+    /* No need to clear config:
+       _PyCoreConfig_GetCoreConfig() doesn't allocate memory */
 }
 
 
 static _PyInitError
-pyinit_coreconfig(_PyCoreConfig *config, const _PyCoreConfig *src_config,
+pyinit_coreconfig(_PyCoreConfig *config,
+                  const _PyCoreConfig *src_config,
+                  const _PyArgv *args,
                   PyInterpreterState **interp_p)
 {
     if (_PyCoreConfig_Copy(config, src_config) < 0) {
         return _Py_INIT_ERR("failed to copy core config");
     }
 
-    _PyInitError err = _PyCoreConfig_Read(config, NULL);
+    _PyInitError err = _PyCoreConfig_Read(config, args);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
@@ -834,21 +836,23 @@ pyinit_coreconfig(_PyCoreConfig *config, const _PyCoreConfig *src_config,
  */
 static _PyInitError
 _Py_InitializeCore(const _PyCoreConfig *src_config,
+                   const _PyArgv *args,
                    PyInterpreterState **interp_p)
 {
     assert(src_config != NULL);
 
-    _PyInitError err = _Py_PreInitializeFromConfig(src_config);
+    _PyInitError err = _Py_PreInitializeFromCoreConfig(src_config);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
 
     _PyCoreConfig local_config = _PyCoreConfig_INIT;
-    err = pyinit_coreconfig(&local_config, src_config, interp_p);
+    err = pyinit_coreconfig(&local_config, src_config, args, interp_p);
     _PyCoreConfig_Clear(&local_config);
     return err;
 }
 
+
 /* Py_Initialize() has already been called: update the main interpreter
    configuration. Example of bpo-34008: Py_Main() called after
    Py_Initialize(). */
@@ -881,7 +885,7 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp)
  * Other errors should be reported as normal Python exceptions with a
  * non-zero return code.
  */
-_PyInitError
+static _PyInitError
 _Py_InitializeMainInterpreter(PyInterpreterState *interp)
 {
     if (!_PyRuntime.core_initialized) {
@@ -980,19 +984,15 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp)
 
 #undef _INIT_DEBUG_PRINT
 
-_PyInitError
-_Py_InitializeFromConfig(const _PyCoreConfig *config,
-                         PyInterpreterState **interp_p)
+static _PyInitError
+init_python(const _PyCoreConfig *config, const _PyArgv *args)
 {
     PyInterpreterState *interp = NULL;
     _PyInitError err;
-    err = _Py_InitializeCore(config, &interp);
+    err = _Py_InitializeCore(config, args, &interp);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
-    if (interp_p) {
-        *interp_p = interp;
-    }
     config = &interp->core_config;
 
     if (config->_init_main) {
@@ -1006,6 +1006,29 @@ _Py_InitializeFromConfig(const _PyCoreConfig *config,
 }
 
 
+_PyInitError
+_Py_InitializeFromArgs(const _PyCoreConfig *config, int argc, char **argv)
+{
+    _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv};
+    return init_python(config, &args);
+}
+
+
+_PyInitError
+_Py_InitializeFromWideArgs(const _PyCoreConfig *config, int argc, wchar_t **argv)
+{
+    _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv};
+    return init_python(config, &args);
+}
+
+
+_PyInitError
+_Py_InitializeFromConfig(const _PyCoreConfig *config)
+{
+    return init_python(config, NULL);
+}
+
+
 void
 Py_InitializeEx(int install_sigs)
 {
@@ -1017,7 +1040,7 @@ Py_InitializeEx(int install_sigs)
     _PyCoreConfig config = _PyCoreConfig_INIT;
     config.install_signal_handlers = install_sigs;
 
-    _PyInitError err = _Py_InitializeFromConfig(&config, NULL);
+    _PyInitError err = _Py_InitializeFromConfig(&config);
     if (_Py_INIT_FAILED(err)) {
         _Py_ExitInitError(err);
     }



More information about the Python-checkins mailing list