bpo-36301: Add _PyRuntime.pre_initialized (GH-12457)

* Add _PyRuntime.pre_initialized: set to 1 when Python
  is pre-initialized
* Add _Py_PreInitialize() and _Py_PreInitializeFromPreConfig().
* _PyCoreConfig_Read() now calls  _Py_PreInitialize().
* Move _PyPreConfig_GetGlobalConfig() and
  _PyCoreConfig_GetGlobalConfig() calls from main.c to preconfig.c
  and coreconfig.c.
This commit is contained in:
Victor Stinner 2019-03-20 02:20:13 +01:00 committed by GitHub
parent 0d765e3849
commit f29084d611
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 77 additions and 27 deletions

View File

@ -14,6 +14,10 @@ PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding,
/* PEP 432 Multi-phase initialization API (Private while provisional!) */ /* 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( PyAPI_FUNC(_PyInitError) _Py_InitializeCore(
PyInterpreterState **interp, PyInterpreterState **interp,
const _PyCoreConfig *); const _PyCoreConfig *);

View File

@ -134,8 +134,15 @@ struct _gilstate_runtime_state {
/* Full Python runtime state */ /* Full Python runtime state */
typedef struct pyruntimestate { 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; int core_initialized;
/* Is Python fully initialized? Set to 1 by Py_Initialize() */
int initialized;
PyThreadState *finalizing; PyThreadState *finalizing;
struct pyinterpreters { struct pyinterpreters {
@ -172,7 +179,8 @@ typedef struct pyruntimestate {
// XXX Consolidate globals found via the check-c-globals script. // XXX Consolidate globals found via the check-c-globals script.
} _PyRuntimeState; } _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 */ /* Note: _PyRuntimeState_INIT sets other fields to 0/NULL */
PyAPI_DATA(_PyRuntimeState) _PyRuntime; PyAPI_DATA(_PyRuntimeState) _PyRuntime;

View File

@ -283,32 +283,30 @@ _PyMainInterpreterConfig_Read(_PyMainInterpreterConfig *main_config,
/* --- pymain_init() ---------------------------------------------- */ /* --- pymain_init() ---------------------------------------------- */
static _PyInitError 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); _PyInitError err = _PyPreConfig_ReadFromArgv(config, args);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; return err;
} }
return _PyPreConfig_Write(config); return _Py_PreInitializeFromPreConfig(config);
} }
static _PyInitError static _PyInitError
config_read_write(_PyCoreConfig *config, const _PyArgv *args, pymain_init_coreconfig(_PyCoreConfig *config, const _PyArgv *args,
const _PyPreConfig *preconfig) const _PyPreConfig *preconfig,
PyInterpreterState **interp_p)
{ {
_PyCoreConfig_GetGlobalConfig(config);
_PyInitError err = _PyCoreConfig_ReadFromArgv(config, args, preconfig); _PyInitError err = _PyCoreConfig_ReadFromArgv(config, args, preconfig);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; return err;
} }
_PyCoreConfig_Write(config); _PyCoreConfig_Write(config);
return _Py_INIT_OK();
return _Py_InitializeCore(interp_p, config);
} }
@ -356,24 +354,17 @@ pymain_init(const _PyArgv *args, PyInterpreterState **interp_p)
_PyCoreConfig local_config = _PyCoreConfig_INIT; _PyCoreConfig local_config = _PyCoreConfig_INIT;
_PyCoreConfig *config = &local_config; _PyCoreConfig *config = &local_config;
err = preconfig_read_write(preconfig, args); err = pymain_init_preconfig(preconfig, args);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
goto done; goto done;
} }
err = config_read_write(config, args, preconfig); err = pymain_init_coreconfig(config, args, preconfig, interp_p);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
goto done; goto done;
} }
PyInterpreterState *interp; err = pymain_init_python_main(*interp_p);
err = _Py_InitializeCore(&interp, config);
if (_Py_INIT_FAILED(err)) {
goto done;
}
*interp_p = interp;
err = pymain_init_python_main(interp);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
goto done; goto done;
} }

View File

@ -1367,6 +1367,11 @@ _PyCoreConfig_Read(_PyCoreConfig *config, const _PyPreConfig *preconfig)
{ {
_PyInitError err; _PyInitError err;
err = _Py_PreInitialize();
if (_Py_INIT_FAILED(err)) {
return err;
}
_PyCoreConfig_GetGlobalConfig(config); _PyCoreConfig_GetGlobalConfig(config);
if (preconfig != NULL) { if (preconfig != NULL) {
@ -2025,6 +2030,8 @@ config_from_cmdline(_PyCoreConfig *config, _PyCmdline *cmdline,
int need_usage = 0; int need_usage = 0;
_PyInitError err; _PyInitError err;
_PyCoreConfig_GetGlobalConfig(config);
err = config_init_program(config, cmdline); err = config_init_program(config, cmdline);
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; return err;

View File

@ -672,6 +672,8 @@ _PyPreConfig_ReadFromArgv(_PyPreConfig *config, const _PyArgv *args)
goto done; goto done;
} }
_PyPreConfig_GetGlobalConfig(config);
if (_PyPreConfig_Copy(&save_config, config) < 0) { if (_PyPreConfig_Copy(&save_config, config) < 0) {
err = _Py_INIT_NO_MEMORY(); err = _Py_INIT_NO_MEMORY();
goto done; goto done;

View File

@ -714,19 +714,57 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p,
} }
static _PyInitError _PyInitError
pyinit_preconfig(_PyPreConfig *preconfig, const _PyPreConfig *src_preconfig) _Py_PreInitializeFromPreConfig(_PyPreConfig *config)
{ {
if (_PyPreConfig_Copy(preconfig, src_preconfig) < 0) { if (config != NULL) {
return _Py_INIT_ERR("failed to copy pre config"); _PyInitError err = _PyPreConfig_Write(config);
if (_Py_INIT_FAILED(err)) {
return err;
}
} }
_PyInitError err = _PyPreConfig_Read(preconfig); _PyRuntime.pre_initialized = 1;
return _Py_INIT_OK();
}
static _PyInitError
pyinit_preconfig(_PyPreConfig *config, const _PyPreConfig *src_config)
{
_PyInitError err;
err = _PyRuntime_Initialize();
if (_Py_INIT_FAILED(err)) { if (_Py_INIT_FAILED(err)) {
return err; return err;
} }
return _PyPreConfig_Write(preconfig); if (_PyPreConfig_Copy(config, src_config) < 0) {
return _Py_INIT_ERR("failed to copy pre config");
}
err = _PyPreConfig_Read(config);
if (_Py_INIT_FAILED(err)) {
return err;
}
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);
} }