summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-03-20 01:20:13 (GMT)
committerGitHub <noreply@github.com>2019-03-20 01:20:13 (GMT)
commitf29084d611a6ca504c99a0967371374febf0ccc3 (patch)
tree4026d6cf02a675a3b34aa5e6b6d9e832cb1830a5
parent0d765e3849f1010276bb349b557b79ed94befa0b (diff)
downloadcpython-f29084d611a6ca504c99a0967371374febf0ccc3.zip
cpython-f29084d611a6ca504c99a0967371374febf0ccc3.tar.gz
cpython-f29084d611a6ca504c99a0967371374febf0ccc3.tar.bz2
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.
-rw-r--r--Include/cpython/pylifecycle.h4
-rw-r--r--Include/internal/pycore_pystate.h12
-rw-r--r--Modules/main.c29
-rw-r--r--Python/coreconfig.c7
-rw-r--r--Python/preconfig.c2
-rw-r--r--Python/pylifecycle.c46
6 files changed, 75 insertions, 25 deletions
diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h
index 3bffc80..1caeb98 100644
--- a/Include/cpython/pylifecycle.h
+++ b/Include/cpython/pylifecycle.h
@@ -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 *);
diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h
index 7c9d11a..911e7ee 100644
--- a/Include/internal/pycore_pystate.h
+++ b/Include/internal/pycore_pystate.h
@@ -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 {
@@ -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;
diff --git a/Modules/main.c b/Modules/main.c
index df4eca5..57cf862 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -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);
}
@@ -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;
}
diff --git a/Python/coreconfig.c b/Python/coreconfig.c
index 0827376..de2058c 100644
--- a/Python/coreconfig.c
+++ b/Python/coreconfig.c
@@ -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) {
@@ -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;
diff --git a/Python/preconfig.c b/Python/preconfig.c
index b034361..a149ea5 100644
--- a/Python/preconfig.c
+++ b/Python/preconfig.c
@@ -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;
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index df9570b..994a94f 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -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);
}