diff --git a/Include/cpython/coreconfig.h b/Include/cpython/coreconfig.h index 53493ff85a3..27ee1f4c63f 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 496dcb2c604..e293b04e3f1 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, - PyInterpreterState **interp_p); + int argc, + char **argv); +PyAPI_FUNC(_PyInitError) _Py_InitializeFromWideArgs( + const _PyCoreConfig *config, + 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 c5f39bac9f8..3a27628aa74 100644 --- a/Include/internal/pycore_coreconfig.h +++ b/Include/internal/pycore_coreconfig.h @@ -9,6 +9,54 @@ extern "C" { #endif +/* --- _PyWstrList ------------------------------------------------ */ + +#ifndef NDEBUG +PyAPI_FUNC(int) _PyWstrList_CheckConsistency(const _PyWstrList *list); +#endif +PyAPI_FUNC(void) _PyWstrList_Clear(_PyWstrList *list); +PyAPI_FUNC(int) _PyWstrList_Copy(_PyWstrList *list, + const _PyWstrList *list2); +PyAPI_FUNC(int) _PyWstrList_Append(_PyWstrList *list, + const wchar_t *item); +PyAPI_FUNC(PyObject*) _PyWstrList_AsList(const _PyWstrList *list); +PyAPI_FUNC(int) _PyWstrList_Extend(_PyWstrList *list, + const _PyWstrList *list2); + + +/* --- _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); + + +/* --- Helper functions ------------------------------------------- */ + +PyAPI_FUNC(int) _Py_str_to_int( + const char *str, + int *result); +PyAPI_FUNC(const wchar_t*) _Py_get_xoption( + const _PyWstrList *xoptions, + const wchar_t *name); +PyAPI_FUNC(const char*) _Py_GetEnv( + int use_environment, + const char *name); +PyAPI_FUNC(void) _Py_get_env_flag( + int use_environment, + int *flag, + const char *name); + +/* Py_GetArgcArgv() helper */ +PyAPI_FUNC(void) _Py_ClearArgcArgv(void); + + /* --- _PyPreCmdline ------------------------------------------------- */ typedef struct { @@ -33,61 +81,19 @@ PyAPI_FUNC(int) _PyPreCmdline_SetCoreConfig( const _PyPreCmdline *cmdline, _PyCoreConfig *config); PyAPI_FUNC(_PyInitError) _PyPreCmdline_Read(_PyPreCmdline *cmdline, - const _PyPreConfig *preconfig, - const _PyCoreConfig *coreconfig); + const _PyPreConfig *preconfig); -/* --- _PyWstrList ------------------------------------------------ */ - -#ifndef NDEBUG -PyAPI_FUNC(int) _PyWstrList_CheckConsistency(const _PyWstrList *list); -#endif -PyAPI_FUNC(void) _PyWstrList_Clear(_PyWstrList *list); -PyAPI_FUNC(int) _PyWstrList_Copy(_PyWstrList *list, - const _PyWstrList *list2); -PyAPI_FUNC(int) _PyWstrList_Append(_PyWstrList *list, - const wchar_t *item); -PyAPI_FUNC(PyObject*) _PyWstrList_AsList(const _PyWstrList *list); -PyAPI_FUNC(int) _PyWstrList_Extend(_PyWstrList *list, - const _PyWstrList *list2); - - -/* --- _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( - const char *str, - int *result); -PyAPI_FUNC(const wchar_t*) _Py_get_xoption( - const _PyWstrList *xoptions, - const wchar_t *name); -PyAPI_FUNC(const char*) _Py_GetEnv( - int use_environment, - const char *name); -PyAPI_FUNC(void) _Py_get_env_flag( - int use_environment, - int *flag, - const char *name); - /* --- _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 3214d6b06bd..d837ea4fb33 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 57d16093dca..ff79edbe43e 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); + _PyCoreConfig config = _PyCoreConfig_INIT; + + if (args->use_bytes_argv) { + err = _Py_PreInitializeFromArgs(NULL, args->argc, args->bytes_argv); + } + else { + err = _Py_PreInitializeFromWideArgs(NULL, args->argc, args->wchar_argv); + } 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) { + return _Py_InitializeFromArgs(&config, args->argc, args->bytes_argv); } - - err = _Py_InitializeFromConfig(&config, interp_p); - if (_Py_INIT_FAILED(err)) { - goto done; + else { + return _Py_InitializeFromWideArgs(&config, args->argc, args->wchar_argv); } - - err = _Py_INIT_OK(); - -done: - _PyCoreConfig_Clear(&config); - return err; } @@ -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 774748dc091..6f77e86a9e6 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 70587990f8d..425954cdd40 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 ecb22e5667d..13aa2272011 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 041b4670ca3..6554aa75b03 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 ce63ef0777a..011ed53a8e7 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 @@ fail: } +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 f255fd9e132..7c6948e6bdb 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); }