Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Include/cpython/pylifecycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ 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(
_PyPreConfig *preconfig);

PyAPI_FUNC(_PyInitError) _Py_InitializeCore(
PyInterpreterState **interp,
const _PyCoreConfig *);
Expand Down
12 changes: 10 additions & 2 deletions Include/internal/pycore_pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,15 @@ struct _gilstate_runtime_state {
/* Full Python runtime state */

typedef struct pyruntimestate {
int initialized;
/* Is Python pre-initialized? Set to 1 by _Py_PreInitialize() */
int pre_initialized;

/* Is Python core initialized? Set to 1 by _Py_InitializeCore() */
int core_initialized;

/* Is Python fully initialized? Set to 1 by Py_Initialize() */
int initialized;

PyThreadState *finalizing;

struct pyinterpreters {
Expand Down Expand Up @@ -172,7 +179,8 @@ typedef struct pyruntimestate {
// XXX Consolidate globals found via the check-c-globals script.
} _PyRuntimeState;

#define _PyRuntimeState_INIT {.initialized = 0, .core_initialized = 0}
#define _PyRuntimeState_INIT \
{.pre_initialized = 0, .core_initialized = 0, .initialized = 0}
/* Note: _PyRuntimeState_INIT sets other fields to 0/NULL */

PyAPI_DATA(_PyRuntimeState) _PyRuntime;
Expand Down
29 changes: 10 additions & 19 deletions Modules/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,32 +283,30 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config,
/* --- pymain_init() ---------------------------------------------- */

static _PyInitError
preconfig_read_write(_PyPreConfig *config, const _PyArgv *args)
pymain_init_preconfig(_PyPreConfig *config, const _PyArgv *args)
{
_PyPreConfig_GetGlobalConfig(config);

_PyInitError err = _PyPreConfig_ReadFromArgv(config, args);
if (_Py_INIT_FAILED(err)) {
return err;
}

return _PyPreConfig_Write(config);
return _Py_PreInitializeFromPreConfig(config);
}


static _PyInitError
config_read_write(_PyCoreConfig *config, const _PyArgv *args,
const _PyPreConfig *preconfig)
pymain_init_coreconfig(_PyCoreConfig *config, const _PyArgv *args,
const _PyPreConfig *preconfig,
PyInterpreterState **interp_p)
{
_PyCoreConfig_GetGlobalConfig(config);

_PyInitError err = _PyCoreConfig_ReadFromArgv(config, args, preconfig);
if (_Py_INIT_FAILED(err)) {
return err;
}

_PyCoreConfig_Write(config);
return _Py_INIT_OK();

return _Py_InitializeCore(interp_p, config);
}


Expand Down Expand Up @@ -356,24 +354,17 @@ pymain_init(const _PyArgv *args, PyInterpreterState **interp_p)
_PyCoreConfig local_config = _PyCoreConfig_INIT;
_PyCoreConfig *config = &local_config;

err = preconfig_read_write(preconfig, args);
err = pymain_init_preconfig(preconfig, args);
if (_Py_INIT_FAILED(err)) {
goto done;
}

err = config_read_write(config, args, preconfig);
if (_Py_INIT_FAILED(err)) {
goto done;
}

PyInterpreterState *interp;
err = _Py_InitializeCore(&interp, config);
err = pymain_init_coreconfig(config, args, preconfig, interp_p);
if (_Py_INIT_FAILED(err)) {
goto done;
}
*interp_p = interp;

err = pymain_init_python_main(interp);
err = pymain_init_python_main(*interp_p);
if (_Py_INIT_FAILED(err)) {
goto done;
}
Expand Down
7 changes: 7 additions & 0 deletions Python/coreconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -1367,6 +1367,11 @@ _PyCoreConfig_Read(_PyCoreConfig *config, const _PyPreConfig *preconfig)
{
_PyInitError err;

err = _Py_PreInitialize();
if (_Py_INIT_FAILED(err)) {
return err;
}

_PyCoreConfig_GetGlobalConfig(config);

if (preconfig != NULL) {
Expand Down Expand Up @@ -2025,6 +2030,8 @@ config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
int need_usage = 0;
_PyInitError err;

_PyCoreConfig_GetGlobalConfig(config);

err = config_init_program(config, cmdline);
if (_Py_INIT_FAILED(err)) {
return err;
Expand Down
2 changes: 2 additions & 0 deletions Python/preconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,8 @@ _PyPreConfig_ReadFromArgv(_PyPreConfig *config, const _PyArgv *args)
goto done;
}

_PyPreConfig_GetGlobalConfig(config);

if (_PyPreConfig_Copy(&save_config, config) < 0) {
err = _Py_INIT_NO_MEMORY();
goto done;
Expand Down
46 changes: 42 additions & 4 deletions Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -714,19 +714,57 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p,
}


_PyInitError
_Py_PreInitializeFromPreConfig(_PyPreConfig *config)
{
if (config != NULL) {
_PyInitError err = _PyPreConfig_Write(config);
if (_Py_INIT_FAILED(err)) {
return err;
}
}

_PyRuntime.pre_initialized = 1;
return _Py_INIT_OK();
}


static _PyInitError
pyinit_preconfig(_PyPreConfig *preconfig, const _PyPreConfig *src_preconfig)
pyinit_preconfig(_PyPreConfig *config, const _PyPreConfig *src_config)
{
if (_PyPreConfig_Copy(preconfig, src_preconfig) < 0) {
_PyInitError err;

err = _PyRuntime_Initialize();
if (_Py_INIT_FAILED(err)) {
return err;
}

if (_PyPreConfig_Copy(config, src_config) < 0) {
return _Py_INIT_ERR("failed to copy pre config");
}

_PyInitError err = _PyPreConfig_Read(preconfig);
err = _PyPreConfig_Read(config);
if (_Py_INIT_FAILED(err)) {
return err;
}

return _PyPreConfig_Write(preconfig);
return _Py_PreInitializeFromPreConfig(config);
}


_PyInitError
_Py_PreInitialize(void)
{
_PyInitError err = _PyRuntime_Initialize();
if (_Py_INIT_FAILED(err)) {
return err;
}

if (_PyRuntime.pre_initialized) {
return _Py_INIT_OK();
}

return _Py_PreInitializeFromPreConfig(NULL);
}


Expand Down