mirror of
https://github.com/python/cpython.git
synced 2025-11-02 06:31:29 +00:00
bpo-38858: Add init_interp_main() subfunction (GH-17347)
Fix new_interpreter() error handling: undo it all if status is an exception.
This commit is contained in:
parent
e0c9ab8e26
commit
b00513636c
1 changed files with 144 additions and 138 deletions
|
|
@ -260,6 +260,7 @@ _Py_LegacyLocaleDetected(int warn)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef MS_WINDOWS
|
||||||
static const char *_C_LOCALE_WARNING =
|
static const char *_C_LOCALE_WARNING =
|
||||||
"Python runtime initialized with LC_CTYPE=C (a locale with default ASCII "
|
"Python runtime initialized with LC_CTYPE=C (a locale with default ASCII "
|
||||||
"encoding), which may cause Unicode compatibility problems. Using C.UTF-8, "
|
"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);
|
PySys_FormatStderr("%s", _C_LOCALE_WARNING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* !defined(MS_WINDOWS) */
|
||||||
|
|
||||||
typedef struct _CandidateLocale {
|
typedef struct _CandidateLocale {
|
||||||
const char *locale_name; /* The locale to try as a coercion target */
|
const char *locale_name; /* The locale to try as a coercion target */
|
||||||
|
|
@ -896,16 +898,16 @@ pyinit_core(_PyRuntimeState *runtime,
|
||||||
configuration. Example of bpo-34008: Py_Main() called after
|
configuration. Example of bpo-34008: Py_Main() called after
|
||||||
Py_Initialize(). */
|
Py_Initialize(). */
|
||||||
static PyStatus
|
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);
|
PyObject *argv = _PyWideStringList_AsList(&config->argv);
|
||||||
if (argv == NULL) {
|
if (argv == NULL) {
|
||||||
return _PyStatus_NO_MEMORY(); \
|
return _PyStatus_NO_MEMORY(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = PyDict_SetItemString(interp->sysdict, "argv", argv);
|
int res = PyDict_SetItemString(tstate->interp->sysdict, "argv", argv);
|
||||||
Py_DECREF(argv);
|
Py_DECREF(argv);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return _PyStatus_ERR("fail to set sys.argv");
|
return _PyStatus_ERR("fail to set sys.argv");
|
||||||
|
|
@ -913,6 +915,116 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp)
|
||||||
return _PyStatus_OK();
|
return _PyStatus_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyStatus
|
||||||
|
init_interp_main(PyThreadState *tstate)
|
||||||
|
{
|
||||||
|
PyStatus status;
|
||||||
|
int is_main_interp = _Py_IsMainInterpreter(tstate);
|
||||||
|
PyInterpreterState *interp = tstate->interp;
|
||||||
|
PyConfig *config = &interp->config;
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
if (is_main_interp) {
|
||||||
|
interp->runtime->initialized = 1;
|
||||||
|
}
|
||||||
|
return _PyStatus_OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = init_importlib_external(tstate);
|
||||||
|
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);
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (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);
|
||||||
|
}
|
||||||
|
|
||||||
|
interp->runtime->initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config->site_import) {
|
||||||
|
status = init_import_site();
|
||||||
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_main_interp) {
|
||||||
|
#ifndef MS_WINDOWS
|
||||||
|
emit_stderr_warning_for_legacy_locale(interp->runtime);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return _PyStatus_OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Update interpreter state based on supplied configuration settings
|
/* Update interpreter state based on supplied configuration settings
|
||||||
*
|
*
|
||||||
* After calling this function, most of the restrictions on the interpreter
|
* After calling this function, most of the restrictions on the interpreter
|
||||||
|
|
@ -927,104 +1039,19 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp)
|
||||||
static PyStatus
|
static PyStatus
|
||||||
pyinit_main(PyThreadState *tstate)
|
pyinit_main(PyThreadState *tstate)
|
||||||
{
|
{
|
||||||
_PyRuntimeState *runtime = tstate->interp->runtime;
|
PyInterpreterState *interp = tstate->interp;
|
||||||
if (!runtime->core_initialized) {
|
if (!interp->runtime->core_initialized) {
|
||||||
return _PyStatus_ERR("runtime core not initialized");
|
return _PyStatus_ERR("runtime core not initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configure the main interpreter */
|
if (interp->runtime->initialized) {
|
||||||
PyInterpreterState *interp = tstate->interp;
|
return _Py_ReconfigureMainInterpreter(tstate);
|
||||||
PyConfig *config = &interp->config;
|
|
||||||
|
|
||||||
if (runtime->initialized) {
|
|
||||||
return _Py_ReconfigureMainInterpreter(interp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!config->_install_importlib) {
|
PyStatus status = init_interp_main(tstate);
|
||||||
/* 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;
|
|
||||||
return _PyStatus_OK();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_PyTime_Init() < 0) {
|
|
||||||
return _PyStatus_ERR("can't initialize time");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_PySys_InitMain(tstate) < 0) {
|
|
||||||
return _PyStatus_ERR("can't finish initializing sys");
|
|
||||||
}
|
|
||||||
|
|
||||||
PyStatus status = init_importlib_external(tstate);
|
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize the faulthandler module */
|
|
||||||
status = _PyFaulthandler_Init(config->faulthandler);
|
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = _PyUnicode_InitEncodings(tstate);
|
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
status = add_main_module(interp);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
runtime->initialized = 1;
|
|
||||||
|
|
||||||
if (config->site_import) {
|
|
||||||
status = init_import_site();
|
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef MS_WINDOWS
|
|
||||||
emit_stderr_warning_for_legacy_locale(runtime);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return _PyStatus_OK();
|
return _PyStatus_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1440,6 +1467,7 @@ Py_Finalize(void)
|
||||||
Py_FinalizeEx();
|
Py_FinalizeEx();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Create and initialize a new interpreter and thread, and return the
|
/* Create and initialize a new interpreter and thread, and return the
|
||||||
new thread. This requires that Py_Initialize() has been called
|
new thread. This requires that Py_Initialize() has been called
|
||||||
first.
|
first.
|
||||||
|
|
@ -1499,7 +1527,7 @@ new_interpreter(PyThreadState **tstate_p)
|
||||||
|
|
||||||
status = _PyConfig_Copy(&interp->config, config);
|
status = _PyConfig_Copy(&interp->config, config);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
goto done;
|
||||||
}
|
}
|
||||||
config = &interp->config;
|
config = &interp->config;
|
||||||
|
|
||||||
|
|
@ -1508,7 +1536,8 @@ new_interpreter(PyThreadState **tstate_p)
|
||||||
/* XXX The following is lax in error checking */
|
/* XXX The following is lax in error checking */
|
||||||
PyObject *modules = PyDict_New();
|
PyObject *modules = PyDict_New();
|
||||||
if (modules == NULL) {
|
if (modules == NULL) {
|
||||||
return _PyStatus_ERR("can't make modules dictionary");
|
status = _PyStatus_ERR("can't make modules dictionary");
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
interp->modules = modules;
|
interp->modules = modules;
|
||||||
|
|
||||||
|
|
@ -1516,101 +1545,78 @@ new_interpreter(PyThreadState **tstate_p)
|
||||||
if (sysmod != NULL) {
|
if (sysmod != NULL) {
|
||||||
interp->sysdict = PyModule_GetDict(sysmod);
|
interp->sysdict = PyModule_GetDict(sysmod);
|
||||||
if (interp->sysdict == NULL) {
|
if (interp->sysdict == NULL) {
|
||||||
goto handle_error;
|
goto handle_exc;
|
||||||
}
|
}
|
||||||
Py_INCREF(interp->sysdict);
|
Py_INCREF(interp->sysdict);
|
||||||
PyDict_SetItemString(interp->sysdict, "modules", modules);
|
PyDict_SetItemString(interp->sysdict, "modules", modules);
|
||||||
if (_PySys_InitMain(tstate) < 0) {
|
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)) {
|
else if (_PyErr_Occurred(tstate)) {
|
||||||
goto handle_error;
|
goto handle_exc;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *bimod = _PyImport_FindBuiltin(tstate, "builtins");
|
PyObject *bimod = _PyImport_FindBuiltin(tstate, "builtins");
|
||||||
if (bimod != NULL) {
|
if (bimod != NULL) {
|
||||||
interp->builtins = PyModule_GetDict(bimod);
|
interp->builtins = PyModule_GetDict(bimod);
|
||||||
if (interp->builtins == NULL)
|
if (interp->builtins == NULL)
|
||||||
goto handle_error;
|
goto handle_exc;
|
||||||
Py_INCREF(interp->builtins);
|
Py_INCREF(interp->builtins);
|
||||||
}
|
}
|
||||||
else if (_PyErr_Occurred(tstate)) {
|
else if (_PyErr_Occurred(tstate)) {
|
||||||
goto handle_error;
|
goto handle_exc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bimod != NULL && sysmod != NULL) {
|
if (bimod != NULL && sysmod != NULL) {
|
||||||
status = _PyBuiltins_AddExceptions(bimod);
|
status = _PyBuiltins_AddExceptions(bimod);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = _PySys_SetPreliminaryStderr(interp->sysdict);
|
status = _PySys_SetPreliminaryStderr(interp->sysdict);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = _PyImportHooks_Init(tstate);
|
status = _PyImportHooks_Init(tstate);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = init_importlib(tstate, sysmod);
|
status = init_importlib(tstate, sysmod);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = init_importlib_external(tstate);
|
status = init_interp_main(tstate);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
goto done;
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_PyErr_Occurred(tstate)) {
|
if (_PyErr_Occurred(tstate)) {
|
||||||
goto handle_error;
|
goto handle_exc;
|
||||||
}
|
}
|
||||||
|
|
||||||
*tstate_p = tstate;
|
*tstate_p = tstate;
|
||||||
return _PyStatus_OK();
|
return _PyStatus_OK();
|
||||||
|
|
||||||
handle_error:
|
handle_exc:
|
||||||
/* Oops, it didn't work. Undo it all. */
|
status = _PyStatus_OK();
|
||||||
|
|
||||||
|
done:
|
||||||
|
*tstate_p = NULL;
|
||||||
|
|
||||||
|
/* Oops, it didn't work. Undo it all. */
|
||||||
PyErr_PrintEx(0);
|
PyErr_PrintEx(0);
|
||||||
PyThreadState_Clear(tstate);
|
PyThreadState_Clear(tstate);
|
||||||
PyThreadState_Delete(tstate);
|
PyThreadState_Delete(tstate);
|
||||||
PyInterpreterState_Delete(interp);
|
PyInterpreterState_Delete(interp);
|
||||||
PyThreadState_Swap(save_tstate);
|
PyThreadState_Swap(save_tstate);
|
||||||
|
|
||||||
*tstate_p = NULL;
|
return status;
|
||||||
return _PyStatus_OK();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PyThreadState *
|
PyThreadState *
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue