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.
This commit is contained in:
Victor Stinner 2019-04-24 18:23:53 +02:00 committed by GitHub
parent 8e91c246e4
commit 43125224d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 104 additions and 71 deletions

View file

@ -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)