[Python-checkins] bpo-36710: Add runtime variable to Py_InitializeEx() (GH-12939)

Victor Stinner webhook-mailer at python.org
Wed Apr 24 12:38:39 EDT 2019


https://github.com/python/cpython/commit/43125224d6da5febb34101ebfd36536d791d68cd
commit: 43125224d6da5febb34101ebfd36536d791d68cd
branch: master
author: Victor Stinner <vstinner at redhat.com>
committer: GitHub <noreply at github.com>
date: 2019-04-24T18:23:53+02:00
summary:

bpo-36710: Add runtime variable to Py_InitializeEx() (GH-12939)

Py_InitializeEx() now uses a runtime variable passed to subfunctions,
rather than working directly on the global variable _PyRuntime.

Add 'runtime' parameter to _PyCoreConfig_Write(), _PySys_Create(),
_PySys_InitMain(), _PyGILState_Init(),
emit_stderr_warning_for_legacy_locale() and other subfunctions.

files:
M Include/internal/pycore_coreconfig.h
M Include/internal/pycore_pylifecycle.h
M Python/coreconfig.c
M Python/pylifecycle.c
M Python/pystate.c
M Python/sysmodule.c

diff --git a/Include/internal/pycore_coreconfig.h b/Include/internal/pycore_coreconfig.h
index e88a46314c89..ac98e00159ce 100644
--- a/Include/internal/pycore_coreconfig.h
+++ b/Include/internal/pycore_coreconfig.h
@@ -8,6 +8,8 @@ extern "C" {
 #  error "this header requires Py_BUILD_CORE define"
 #endif
 
+#include "pycore_pystate.h"   /* _PyRuntimeState */
+
 
 /* --- _PyWstrList ------------------------------------------------ */
 
@@ -108,7 +110,8 @@ PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPathConfig(
     const _PyCoreConfig *config);
 PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config,
     const _PyArgv *args);
-PyAPI_FUNC(void) _PyCoreConfig_Write(const _PyCoreConfig *config);
+PyAPI_FUNC(void) _PyCoreConfig_Write(const _PyCoreConfig *config,
+    _PyRuntimeState *runtime);
 
 
 /* --- Function used for testing ---------------------------------- */
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h
index f07bc427bb88..69709b10b8f8 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -34,10 +34,13 @@ extern _PyInitError _PyFaulthandler_Init(int enable);
 extern int _PyTraceMalloc_Init(int enable);
 extern PyObject * _PyBuiltin_Init(void);
 extern _PyInitError _PySys_Create(
+    _PyRuntimeState *runtime,
     PyInterpreterState *interp,
     PyObject **sysmod_p);
 extern _PyInitError _PySys_SetPreliminaryStderr(PyObject *sysdict);
-extern int _PySys_InitMain(PyInterpreterState *interp);
+extern int _PySys_InitMain(
+    _PyRuntimeState *runtime,
+    PyInterpreterState *interp);
 extern _PyInitError _PyImport_Init(PyInterpreterState *interp);
 extern _PyInitError _PyExc_Init(void);
 extern _PyInitError _PyBuiltins_AddExceptions(PyObject * bltinmod);
@@ -74,7 +77,10 @@ extern void _PyFaulthandler_Fini(void);
 extern void _PyHash_Fini(void);
 extern int _PyTraceMalloc_Fini(void);
 
-extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *);
+extern void _PyGILState_Init(
+    _PyRuntimeState *runtime,
+    PyInterpreterState *interp,
+    PyThreadState *tstate);
 extern void _PyGILState_Fini(_PyRuntimeState *runtime);
 
 PyAPI_FUNC(void) _PyGC_DumpShutdownStats(void);
diff --git a/Python/coreconfig.c b/Python/coreconfig.c
index 7b55b06b7a6e..d05beef2aa55 100644
--- a/Python/coreconfig.c
+++ b/Python/coreconfig.c
@@ -1605,13 +1605,13 @@ config_init_stdio(const _PyCoreConfig *config)
    - set Py_xxx global configuration variables
    - initialize C standard streams (stdin, stdout, stderr) */
 void
-_PyCoreConfig_Write(const _PyCoreConfig *config)
+_PyCoreConfig_Write(const _PyCoreConfig *config, _PyRuntimeState *runtime)
 {
     _PyCoreConfig_SetGlobalConfig(config);
     config_init_stdio(config);
 
     /* Write the new pre-configuration into _PyRuntime */
-    _PyPreConfig *preconfig = &_PyRuntime.preconfig;
+    _PyPreConfig *preconfig = &runtime->preconfig;
     preconfig->isolated = config->isolated;
     preconfig->use_environment = config->use_environment;
     preconfig->dev_mode = config->dev_mode;
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index fe4cb97a4740..03486c3b195a 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -286,9 +286,9 @@ static const char *_C_LOCALE_WARNING =
     "locales is recommended.\n";
 
 static void
-_emit_stderr_warning_for_legacy_locale(void)
+emit_stderr_warning_for_legacy_locale(_PyRuntimeState *runtime)
 {
-    const _PyPreConfig *preconfig = &_PyRuntime.preconfig;
+    const _PyPreConfig *preconfig = &runtime->preconfig;
     if (preconfig->coerce_c_locale_warn && _Py_LegacyLocaleDetected()) {
         PySys_FormatStderr("%s", _C_LOCALE_WARNING);
     }
@@ -468,7 +468,8 @@ _Py_SetLocaleFromEnv(int category)
 */
 
 static _PyInitError
-_Py_Initialize_ReconfigureCore(PyInterpreterState **interp_p,
+_Py_Initialize_ReconfigureCore(_PyRuntimeState *runtime,
+                               PyInterpreterState **interp_p,
                                const _PyCoreConfig *core_config)
 {
     PyThreadState *tstate = _PyThreadState_GET();
@@ -482,7 +483,7 @@ _Py_Initialize_ReconfigureCore(PyInterpreterState **interp_p,
     }
     *interp_p = interp;
 
-    _PyCoreConfig_Write(core_config);
+    _PyCoreConfig_Write(core_config, runtime);
 
     if (_PyCoreConfig_Copy(&interp->core_config, core_config) < 0) {
         return _Py_INIT_NO_MEMORY();
@@ -500,18 +501,14 @@ _Py_Initialize_ReconfigureCore(PyInterpreterState **interp_p,
 
 
 static _PyInitError
-pycore_init_runtime(const _PyCoreConfig *core_config)
+pycore_init_runtime(_PyRuntimeState *runtime,
+                    const _PyCoreConfig *core_config)
 {
-    if (_PyRuntime.initialized) {
+    if (runtime->initialized) {
         return _Py_INIT_ERR("main interpreter already initialized");
     }
 
-    _PyCoreConfig_Write(core_config);
-
-    _PyInitError err = _PyRuntime_Initialize();
-    if (_Py_INIT_FAILED(err)) {
-        return err;
-    }
+    _PyCoreConfig_Write(core_config, runtime);
 
     /* Py_Finalize leaves _Py_Finalizing set in order to help daemon
      * threads behave a little more gracefully at interpreter shutdown.
@@ -522,14 +519,14 @@ pycore_init_runtime(const _PyCoreConfig *core_config)
      * threads still hanging around from a previous Py_Initialize/Finalize
      * pair :(
      */
-    _PyRuntime.finalizing = NULL;
+    runtime->finalizing = NULL;
 
-    err = _Py_HashRandomization_Init(core_config);
+    _PyInitError err = _Py_HashRandomization_Init(core_config);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
 
-    err = _PyInterpreterState_Enable(&_PyRuntime);
+    err = _PyInterpreterState_Enable(runtime);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
@@ -538,7 +535,8 @@ pycore_init_runtime(const _PyCoreConfig *core_config)
 
 
 static _PyInitError
-pycore_create_interpreter(const _PyCoreConfig *core_config,
+pycore_create_interpreter(_PyRuntimeState *runtime,
+                          const _PyCoreConfig *core_config,
                           PyInterpreterState **interp_p)
 {
     PyInterpreterState *interp = PyInterpreterState_New();
@@ -565,7 +563,7 @@ pycore_create_interpreter(const _PyCoreConfig *core_config,
     _PyEval_FiniThreads();
 
     /* Auto-thread-state API */
-    _PyGILState_Init(interp, tstate);
+    _PyGILState_Init(runtime, interp, tstate);
 
     /* Create the GIL */
     PyEval_InitThreads();
@@ -671,19 +669,20 @@ pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod)
 
 
 static _PyInitError
-_Py_InitializeCore_impl(PyInterpreterState **interp_p,
+_Py_InitializeCore_impl(_PyRuntimeState *runtime,
+                        PyInterpreterState **interp_p,
                         const _PyCoreConfig *core_config)
 {
     PyInterpreterState *interp;
 
-    _PyCoreConfig_Write(core_config);
+    _PyCoreConfig_Write(core_config, runtime);
 
-    _PyInitError err = pycore_init_runtime(core_config);
+    _PyInitError err = pycore_init_runtime(runtime, core_config);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
 
-    err = pycore_create_interpreter(core_config, &interp);
+    err = pycore_create_interpreter(runtime, core_config, &interp);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
@@ -696,7 +695,7 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p,
     }
 
     PyObject *sysmod;
-    err = _PySys_Create(interp, &sysmod);
+    err = _PySys_Create(runtime, interp, &sysmod);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
@@ -712,7 +711,7 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p,
     }
 
     /* Only when we get here is the runtime core fully initialized */
-    _PyRuntime.core_initialized = 1;
+    runtime->core_initialized = 1;
     return _Py_INIT_OK();
 }
 
@@ -726,8 +725,9 @@ preinit(const _PyPreConfig *src_config, const _PyArgv *args)
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
+    _PyRuntimeState *runtime = &_PyRuntime;
 
-    if (_PyRuntime.pre_initialized) {
+    if (runtime->pre_initialized) {
         /* If it's already configured: ignored the new configuration */
         return _Py_INIT_OK();
     }
@@ -751,7 +751,7 @@ preinit(const _PyPreConfig *src_config, const _PyArgv *args)
         goto done;
     }
 
-    _PyRuntime.pre_initialized = 1;
+    runtime->pre_initialized = 1;
     err = _Py_INIT_OK();
 
 done:
@@ -795,7 +795,8 @@ _Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig)
 
 
 static _PyInitError
-pyinit_coreconfig(_PyCoreConfig *config,
+pyinit_coreconfig(_PyRuntimeState *runtime,
+                  _PyCoreConfig *config,
                   const _PyCoreConfig *src_config,
                   const _PyArgv *args,
                   PyInterpreterState **interp_p)
@@ -811,11 +812,11 @@ pyinit_coreconfig(_PyCoreConfig *config,
         return err;
     }
 
-    if (!_PyRuntime.core_initialized) {
-        return _Py_InitializeCore_impl(interp_p, config);
+    if (!runtime->core_initialized) {
+        return _Py_InitializeCore_impl(runtime, interp_p, config);
     }
     else {
-        return _Py_Initialize_ReconfigureCore(interp_p, config);
+        return _Py_Initialize_ReconfigureCore(runtime, interp_p, config);
     }
 }
 
@@ -838,7 +839,8 @@ pyinit_coreconfig(_PyCoreConfig *config,
  * safe to call without calling Py_Initialize first)
  */
 static _PyInitError
-_Py_InitializeCore(const _PyCoreConfig *src_config,
+_Py_InitializeCore(_PyRuntimeState *runtime,
+                   const _PyCoreConfig *src_config,
                    const _PyArgv *args,
                    PyInterpreterState **interp_p)
 {
@@ -855,7 +857,7 @@ _Py_InitializeCore(const _PyCoreConfig *src_config,
     }
 
     _PyCoreConfig local_config = _PyCoreConfig_INIT;
-    err = pyinit_coreconfig(&local_config, src_config, args, interp_p);
+    err = pyinit_coreconfig(runtime, &local_config, src_config, args, interp_p);
     _PyCoreConfig_Clear(&local_config);
     return err;
 }
@@ -894,16 +896,17 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp)
  * non-zero return code.
  */
 static _PyInitError
-_Py_InitializeMainInterpreter(PyInterpreterState *interp)
+_Py_InitializeMainInterpreter(_PyRuntimeState *runtime,
+                              PyInterpreterState *interp)
 {
-    if (!_PyRuntime.core_initialized) {
+    if (!runtime->core_initialized) {
         return _Py_INIT_ERR("runtime core not initialized");
     }
 
     /* Configure the main interpreter */
     _PyCoreConfig *core_config = &interp->core_config;
 
-    if (_PyRuntime.initialized) {
+    if (runtime->initialized) {
         return _Py_ReconfigureMainInterpreter(interp);
     }
 
@@ -913,7 +916,7 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp)
          * This means anything which needs support from extension modules
          * or pure Python code in the standard library won't work.
          */
-        _PyRuntime.initialized = 1;
+        runtime->initialized = 1;
         return _Py_INIT_OK();
     }
 
@@ -921,7 +924,7 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp)
         return _Py_INIT_ERR("can't initialize time");
     }
 
-    if (_PySys_InitMain(interp) < 0) {
+    if (_PySys_InitMain(runtime, interp) < 0) {
         return _Py_INIT_ERR("can't finish initializing sys");
     }
 
@@ -974,7 +977,7 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp)
         Py_XDECREF(warnings_module);
     }
 
-    _PyRuntime.initialized = 1;
+    runtime->initialized = 1;
 
     if (core_config->site_import) {
         err = initsite(); /* Module site */
@@ -984,7 +987,7 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp)
     }
 
 #ifndef MS_WINDOWS
-    _emit_stderr_warning_for_legacy_locale();
+    emit_stderr_warning_for_legacy_locale(runtime);
 #endif
 
     return _Py_INIT_OK();
@@ -995,16 +998,23 @@ _Py_InitializeMainInterpreter(PyInterpreterState *interp)
 static _PyInitError
 init_python(const _PyCoreConfig *config, const _PyArgv *args)
 {
-    PyInterpreterState *interp = NULL;
     _PyInitError err;
-    err = _Py_InitializeCore(config, args, &interp);
+
+    err = _PyRuntime_Initialize();
+    if (_Py_INIT_FAILED(err)) {
+        return err;
+    }
+    _PyRuntimeState *runtime = &_PyRuntime;
+
+    PyInterpreterState *interp = NULL;
+    err = _Py_InitializeCore(runtime, config, args, &interp);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }
     config = &interp->core_config;
 
     if (config->_init_main) {
-        err = _Py_InitializeMainInterpreter(interp);
+        err = _Py_InitializeMainInterpreter(runtime, interp);
         if (_Py_INIT_FAILED(err)) {
             return err;
         }
@@ -1040,7 +1050,15 @@ _Py_InitializeFromConfig(const _PyCoreConfig *config)
 void
 Py_InitializeEx(int install_sigs)
 {
-    if (_PyRuntime.initialized) {
+    _PyInitError err;
+
+    err = _PyRuntime_Initialize();
+    if (_Py_INIT_FAILED(err)) {
+        _Py_ExitInitError(err);
+    }
+    _PyRuntimeState *runtime = &_PyRuntime;
+
+    if (runtime->initialized) {
         /* bpo-33932: Calling Py_Initialize() twice does nothing. */
         return;
     }
@@ -1048,7 +1066,7 @@ Py_InitializeEx(int install_sigs)
     _PyCoreConfig config = _PyCoreConfig_INIT;
     config.install_signal_handlers = install_sigs;
 
-    _PyInitError err = _Py_InitializeFromConfig(&config);
+    err = _Py_InitializeFromConfig(&config);
     if (_Py_INIT_FAILED(err)) {
         _Py_ExitInitError(err);
     }
@@ -1364,12 +1382,15 @@ Py_Finalize(void)
 static _PyInitError
 new_interpreter(PyThreadState **tstate_p)
 {
-    PyInterpreterState *interp;
-    PyThreadState *tstate, *save_tstate;
-    PyObject *bimod, *sysmod;
     _PyInitError err;
 
-    if (!_PyRuntime.initialized) {
+    err = _PyRuntime_Initialize();
+    if (_Py_INIT_FAILED(err)) {
+        return err;
+    }
+    _PyRuntimeState *runtime = &_PyRuntime;
+
+    if (!runtime->initialized) {
         return _Py_INIT_ERR("Py_Initialize must be called first");
     }
 
@@ -1377,20 +1398,20 @@ new_interpreter(PyThreadState **tstate_p)
        interpreters: disable PyGILState_Check(). */
     _PyGILState_check_enabled = 0;
 
-    interp = PyInterpreterState_New();
+    PyInterpreterState *interp = PyInterpreterState_New();
     if (interp == NULL) {
         *tstate_p = NULL;
         return _Py_INIT_OK();
     }
 
-    tstate = PyThreadState_New(interp);
+    PyThreadState *tstate = PyThreadState_New(interp);
     if (tstate == NULL) {
         PyInterpreterState_Delete(interp);
         *tstate_p = NULL;
         return _Py_INIT_OK();
     }
 
-    save_tstate = PyThreadState_Swap(tstate);
+    PyThreadState *save_tstate = PyThreadState_Swap(tstate);
 
     /* Copy the current interpreter config into the new interpreter */
     _PyCoreConfig *core_config;
@@ -1419,14 +1440,15 @@ new_interpreter(PyThreadState **tstate_p)
     }
     interp->modules = modules;
 
-    sysmod = _PyImport_FindBuiltin("sys", modules);
+    PyObject *sysmod = _PyImport_FindBuiltin("sys", modules);
     if (sysmod != NULL) {
         interp->sysdict = PyModule_GetDict(sysmod);
-        if (interp->sysdict == NULL)
+        if (interp->sysdict == NULL) {
             goto handle_error;
+        }
         Py_INCREF(interp->sysdict);
         PyDict_SetItemString(interp->sysdict, "modules", modules);
-        if (_PySys_InitMain(interp) < 0) {
+        if (_PySys_InitMain(runtime, interp) < 0) {
             return _Py_INIT_ERR("can't finish initializing sys");
         }
     }
@@ -1434,7 +1456,7 @@ new_interpreter(PyThreadState **tstate_p)
         goto handle_error;
     }
 
-    bimod = _PyImport_FindBuiltin("builtins", modules);
+    PyObject *bimod = _PyImport_FindBuiltin("builtins", modules);
     if (bimod != NULL) {
         interp->builtins = PyModule_GetDict(bimod);
         if (interp->builtins == NULL)
diff --git a/Python/pystate.c b/Python/pystate.c
index 498a9546e1b8..a413f9d7ab4c 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1052,13 +1052,13 @@ PyThreadState_IsCurrent(PyThreadState *tstate)
    Py_Initialize/Py_FinalizeEx
 */
 void
-_PyGILState_Init(PyInterpreterState *interp, PyThreadState *tstate)
+_PyGILState_Init(_PyRuntimeState *runtime,
+                 PyInterpreterState *interp, PyThreadState *tstate)
 {
     /* must init with valid states */
     assert(interp != NULL);
     assert(tstate != NULL);
 
-    _PyRuntimeState *runtime = &_PyRuntime;
     struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
 
     if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) {
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 3de94e8468be..0f7af2c69da5 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -2155,12 +2155,12 @@ static PyStructSequence_Desc flags_desc = {
 };
 
 static PyObject*
-make_flags(void)
+make_flags(_PyRuntimeState *runtime, PyInterpreterState *interp)
 {
     int pos = 0;
     PyObject *seq;
-    const _PyPreConfig *preconfig = &_PyRuntime.preconfig;
-    const _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config;
+    const _PyPreConfig *preconfig = &runtime->preconfig;
+    const _PyCoreConfig *config = &interp->core_config;
 
     seq = PyStructSequence_New(&FlagsType);
     if (seq == NULL)
@@ -2375,7 +2375,8 @@ static struct PyModuleDef sysmodule = {
     } while (0)
 
 static _PyInitError
-_PySys_InitCore(PyObject *sysdict)
+_PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp,
+                PyObject *sysdict)
 {
     PyObject *version_info;
     int res;
@@ -2465,8 +2466,8 @@ _PySys_InitCore(PyObject *sysdict)
             goto type_init_failed;
         }
     }
-    /* Set flags to their default values */
-    SET_SYS_FROM_STRING("flags", make_flags());
+    /* Set flags to their default values (updated by _PySys_InitMain()) */
+    SET_SYS_FROM_STRING("flags", make_flags(runtime, interp));
 
 #if defined(MS_WINDOWS)
     /* getwindowsversion */
@@ -2587,7 +2588,7 @@ sys_create_xoptions_dict(const _PyCoreConfig *config)
 
 
 int
-_PySys_InitMain(PyInterpreterState *interp)
+_PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp)
 {
     PyObject *sysdict = interp->sysdict;
     const _PyCoreConfig *config = &interp->core_config;
@@ -2641,7 +2642,7 @@ _PySys_InitMain(PyInterpreterState *interp)
 #undef SET_SYS_FROM_WSTR
 
     /* Set flags to their final values */
-    SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags());
+    SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(runtime, interp));
     /* prevent user from creating new instances */
     FlagsType.tp_init = NULL;
     FlagsType.tp_new = NULL;
@@ -2708,7 +2709,8 @@ _PySys_SetPreliminaryStderr(PyObject *sysdict)
 /* Create sys module without all attributes: _PySys_InitMain() should be called
    later to add remaining attributes. */
 _PyInitError
-_PySys_Create(PyInterpreterState *interp, PyObject **sysmod_p)
+_PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp,
+              PyObject **sysmod_p)
 {
     PyObject *modules = PyDict_New();
     if (modules == NULL) {
@@ -2737,7 +2739,7 @@ _PySys_Create(PyInterpreterState *interp, PyObject **sysmod_p)
         return err;
     }
 
-    err = _PySys_InitCore(sysdict);
+    err = _PySys_InitCore(runtime, interp, sysdict);
     if (_Py_INIT_FAILED(err)) {
         return err;
     }



More information about the Python-checkins mailing list