diff options
author | Victor Stinner <vstinner@python.org> | 2019-11-22 16:52:42 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-22 16:52:42 (GMT) |
commit | b00513636c9891deba4cae50217e25e8faf6c6ac (patch) | |
tree | cb89f289edeb47e66cf5cb33c6ede6fd05ac8a98 /Python/pylifecycle.c | |
parent | e0c9ab8e26d1648b870b80c296b2490a5e9553e5 (diff) | |
download | cpython-b00513636c9891deba4cae50217e25e8faf6c6ac.zip cpython-b00513636c9891deba4cae50217e25e8faf6c6ac.tar.gz cpython-b00513636c9891deba4cae50217e25e8faf6c6ac.tar.bz2 |
bpo-38858: Add init_interp_main() subfunction (GH-17347)
Fix new_interpreter() error handling: undo it all if status is an
exception.
Diffstat (limited to 'Python/pylifecycle.c')
-rw-r--r-- | Python/pylifecycle.c | 212 |
1 files changed, 109 insertions, 103 deletions
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 4825b8b..e692d75 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -260,6 +260,7 @@ _Py_LegacyLocaleDetected(int warn) #endif } +#ifndef MS_WINDOWS static const char *_C_LOCALE_WARNING = "Python runtime initialized with LC_CTYPE=C (a locale with default ASCII " "encoding), which may cause Unicode compatibility problems. Using C.UTF-8, " @@ -274,6 +275,7 @@ emit_stderr_warning_for_legacy_locale(_PyRuntimeState *runtime) PySys_FormatStderr("%s", _C_LOCALE_WARNING); } } +#endif /* !defined(MS_WINDOWS) */ typedef struct _CandidateLocale { const char *locale_name; /* The locale to try as a coercion target */ @@ -896,16 +898,16 @@ done: configuration. Example of bpo-34008: Py_Main() called after Py_Initialize(). */ static PyStatus -_Py_ReconfigureMainInterpreter(PyInterpreterState *interp) +_Py_ReconfigureMainInterpreter(PyThreadState *tstate) { - PyConfig *config = &interp->config; + PyConfig *config = &tstate->interp->config; PyObject *argv = _PyWideStringList_AsList(&config->argv); if (argv == NULL) { return _PyStatus_NO_MEMORY(); \ } - int res = PyDict_SetItemString(interp->sysdict, "argv", argv); + int res = PyDict_SetItemString(tstate->interp->sysdict, "argv", argv); Py_DECREF(argv); if (res < 0) { return _PyStatus_ERR("fail to set sys.argv"); @@ -913,60 +915,48 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp) return _PyStatus_OK(); } -/* Update interpreter state based on supplied configuration settings - * - * After calling this function, most of the restrictions on the interpreter - * are lifted. The only remaining incomplete settings are those related - * to the main module (sys.argv[0], __main__ metadata) - * - * Calling this when the interpreter is not initializing, is already - * initialized or without a valid current thread state is a fatal error. - * Other errors should be reported as normal Python exceptions with a - * non-zero return code. - */ + static PyStatus -pyinit_main(PyThreadState *tstate) +init_interp_main(PyThreadState *tstate) { - _PyRuntimeState *runtime = tstate->interp->runtime; - if (!runtime->core_initialized) { - return _PyStatus_ERR("runtime core not initialized"); - } - - /* Configure the main interpreter */ + PyStatus status; + int is_main_interp = _Py_IsMainInterpreter(tstate); PyInterpreterState *interp = tstate->interp; PyConfig *config = &interp->config; - if (runtime->initialized) { - return _Py_ReconfigureMainInterpreter(interp); - } - if (!config->_install_importlib) { /* Special mode for freeze_importlib: run with no import system * * This means anything which needs support from extension modules * or pure Python code in the standard library won't work. */ - runtime->initialized = 1; + if (is_main_interp) { + interp->runtime->initialized = 1; + } return _PyStatus_OK(); } - if (_PyTime_Init() < 0) { - return _PyStatus_ERR("can't initialize time"); - } + if (is_main_interp) { + if (_PyTime_Init() < 0) { + return _PyStatus_ERR("can't initialize time"); + } - if (_PySys_InitMain(tstate) < 0) { - return _PyStatus_ERR("can't finish initializing sys"); + if (_PySys_InitMain(tstate) < 0) { + return _PyStatus_ERR("can't finish initializing sys"); + } } - PyStatus status = init_importlib_external(tstate); + status = init_importlib_external(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } - /* initialize the faulthandler module */ - status = _PyFaulthandler_Init(config->faulthandler); - if (_PyStatus_EXCEPTION(status)) { - return status; + if (is_main_interp) { + /* initialize the faulthandler module */ + status = _PyFaulthandler_Init(config->faulthandler); + if (_PyStatus_EXCEPTION(status)) { + return status; + } } status = _PyUnicode_InitEncodings(tstate); @@ -974,45 +964,49 @@ pyinit_main(PyThreadState *tstate) return status; } - if (config->install_signal_handlers) { - status = init_signals(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; + if (is_main_interp) { + if (config->install_signal_handlers) { + status = init_signals(tstate); + if (_PyStatus_EXCEPTION(status)) { + return status; + } } - } - if (_PyTraceMalloc_Init(config->tracemalloc) < 0) { - return _PyStatus_ERR("can't initialize tracemalloc"); + if (_PyTraceMalloc_Init(config->tracemalloc) < 0) { + return _PyStatus_ERR("can't initialize tracemalloc"); + } } - status = add_main_module(interp); + status = init_sys_streams(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } - status = init_sys_streams(tstate); + status = init_set_builtins_open(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } - status = init_set_builtins_open(tstate); + status = add_main_module(interp); if (_PyStatus_EXCEPTION(status)) { return status; } - /* Initialize warnings. */ - PyObject *warnoptions = PySys_GetObject("warnoptions"); - if (warnoptions != NULL && PyList_Size(warnoptions) > 0) - { - PyObject *warnings_module = PyImport_ImportModule("warnings"); - if (warnings_module == NULL) { - fprintf(stderr, "'import warnings' failed; traceback:\n"); - _PyErr_Print(tstate); + if (is_main_interp) { + /* Initialize warnings. */ + PyObject *warnoptions = PySys_GetObject("warnoptions"); + if (warnoptions != NULL && PyList_Size(warnoptions) > 0) + { + PyObject *warnings_module = PyImport_ImportModule("warnings"); + if (warnings_module == NULL) { + fprintf(stderr, "'import warnings' failed; traceback:\n"); + _PyErr_Print(tstate); + } + Py_XDECREF(warnings_module); } - Py_XDECREF(warnings_module); - } - runtime->initialized = 1; + interp->runtime->initialized = 1; + } if (config->site_import) { status = init_import_site(); @@ -1021,14 +1015,47 @@ pyinit_main(PyThreadState *tstate) } } + if (is_main_interp) { #ifndef MS_WINDOWS - emit_stderr_warning_for_legacy_locale(runtime); + emit_stderr_warning_for_legacy_locale(interp->runtime); #endif + } return _PyStatus_OK(); } +/* Update interpreter state based on supplied configuration settings + * + * After calling this function, most of the restrictions on the interpreter + * are lifted. The only remaining incomplete settings are those related + * to the main module (sys.argv[0], __main__ metadata) + * + * Calling this when the interpreter is not initializing, is already + * initialized or without a valid current thread state is a fatal error. + * Other errors should be reported as normal Python exceptions with a + * non-zero return code. + */ +static PyStatus +pyinit_main(PyThreadState *tstate) +{ + PyInterpreterState *interp = tstate->interp; + if (!interp->runtime->core_initialized) { + return _PyStatus_ERR("runtime core not initialized"); + } + + if (interp->runtime->initialized) { + return _Py_ReconfigureMainInterpreter(tstate); + } + + PyStatus status = init_interp_main(tstate); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + return _PyStatus_OK(); +} + + PyStatus _Py_InitializeMain(void) { @@ -1440,6 +1467,7 @@ Py_Finalize(void) Py_FinalizeEx(); } + /* Create and initialize a new interpreter and thread, and return the new thread. This requires that Py_Initialize() has been called first. @@ -1499,7 +1527,7 @@ new_interpreter(PyThreadState **tstate_p) status = _PyConfig_Copy(&interp->config, config); if (_PyStatus_EXCEPTION(status)) { - return status; + goto done; } config = &interp->config; @@ -1508,7 +1536,8 @@ new_interpreter(PyThreadState **tstate_p) /* XXX The following is lax in error checking */ PyObject *modules = PyDict_New(); if (modules == NULL) { - return _PyStatus_ERR("can't make modules dictionary"); + status = _PyStatus_ERR("can't make modules dictionary"); + goto done; } interp->modules = modules; @@ -1516,101 +1545,78 @@ new_interpreter(PyThreadState **tstate_p) if (sysmod != NULL) { interp->sysdict = PyModule_GetDict(sysmod); if (interp->sysdict == NULL) { - goto handle_error; + goto handle_exc; } Py_INCREF(interp->sysdict); PyDict_SetItemString(interp->sysdict, "modules", modules); if (_PySys_InitMain(tstate) < 0) { - return _PyStatus_ERR("can't finish initializing sys"); + status = _PyStatus_ERR("can't finish initializing sys"); + goto done; } } else if (_PyErr_Occurred(tstate)) { - goto handle_error; + goto handle_exc; } PyObject *bimod = _PyImport_FindBuiltin(tstate, "builtins"); if (bimod != NULL) { interp->builtins = PyModule_GetDict(bimod); if (interp->builtins == NULL) - goto handle_error; + goto handle_exc; Py_INCREF(interp->builtins); } else if (_PyErr_Occurred(tstate)) { - goto handle_error; + goto handle_exc; } if (bimod != NULL && sysmod != NULL) { status = _PyBuiltins_AddExceptions(bimod); if (_PyStatus_EXCEPTION(status)) { - return status; + goto done; } status = _PySys_SetPreliminaryStderr(interp->sysdict); if (_PyStatus_EXCEPTION(status)) { - return status; + goto done; } status = _PyImportHooks_Init(tstate); if (_PyStatus_EXCEPTION(status)) { - return status; + goto done; } status = init_importlib(tstate, sysmod); if (_PyStatus_EXCEPTION(status)) { - return status; + goto done; } - status = init_importlib_external(tstate); + status = init_interp_main(tstate); if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = _PyUnicode_InitEncodings(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = init_sys_streams(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = init_set_builtins_open(tstate); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - status = add_main_module(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - - if (config->site_import) { - status = init_import_site(); - if (_PyStatus_EXCEPTION(status)) { - return status; - } + goto done; } } if (_PyErr_Occurred(tstate)) { - goto handle_error; + goto handle_exc; } *tstate_p = tstate; return _PyStatus_OK(); -handle_error: - /* Oops, it didn't work. Undo it all. */ +handle_exc: + status = _PyStatus_OK(); +done: + *tstate_p = NULL; + + /* Oops, it didn't work. Undo it all. */ PyErr_PrintEx(0); PyThreadState_Clear(tstate); PyThreadState_Delete(tstate); PyInterpreterState_Delete(interp); PyThreadState_Swap(save_tstate); - *tstate_p = NULL; - return _PyStatus_OK(); + return status; } PyThreadState * |