From 81fe5bd3d78f9bb955f8255404d99df27a31c36a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Dec 2019 02:43:30 +0100 Subject: [PATCH] bpo-38858: new_interpreter() reuses _PySys_Create() (GH-17481) new_interpreter() now calls _PySys_Create() to create a new sys module isolated from the main interpreter. It now calls _PySys_InitCore() and _PyImport_FixupBuiltin(). init_interp_main() now calls _PySys_InitMain(). --- Include/internal/pycore_pylifecycle.h | 1 - Python/pylifecycle.c | 81 +++++++++++---------------- Python/sysmodule.c | 19 +++++-- 3 files changed, 46 insertions(+), 55 deletions(-) diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index cd3be215ff1..4e4bbc2bed0 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -40,7 +40,6 @@ extern PyObject * _PyBuiltin_Init(PyThreadState *tstate); extern PyStatus _PySys_Create( PyThreadState *tstate, PyObject **sysmod_p); -extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict); extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options); extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config); extern int _PySys_InitMain(PyThreadState *tstate); diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 410156b8021..9822cce4ae3 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -622,6 +622,8 @@ pycore_init_types(PyThreadState *tstate) static PyStatus pycore_init_builtins(PyThreadState *tstate) { + assert(!_PyErr_Occurred(tstate)); + PyObject *bimod = _PyBuiltin_Init(tstate); if (bimod == NULL) { goto error; @@ -649,6 +651,9 @@ pycore_init_builtins(PyThreadState *tstate) goto error; } Py_DECREF(bimod); + + assert(!_PyErr_Occurred(tstate)); + return _PyStatus_OK(); error: @@ -660,13 +665,14 @@ pycore_init_builtins(PyThreadState *tstate) static PyStatus pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod) { - const PyConfig *config = &tstate->interp->config; + assert(!_PyErr_Occurred(tstate)); PyStatus status = _PyImportHooks_Init(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } + const PyConfig *config = &tstate->interp->config; if (_Py_IsMainInterpreter(tstate)) { /* Initialize _warnings. */ if (_PyWarnings_Init() == NULL) { @@ -688,6 +694,9 @@ pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod) return status; } } + + assert(!_PyErr_Occurred(tstate)); + return _PyStatus_OK(); } @@ -929,6 +938,8 @@ _Py_ReconfigureMainInterpreter(PyThreadState *tstate) static PyStatus init_interp_main(PyThreadState *tstate) { + assert(!_PyErr_Occurred(tstate)); + PyStatus status; int is_main_interp = _Py_IsMainInterpreter(tstate); PyInterpreterState *interp = tstate->interp; @@ -950,10 +961,10 @@ init_interp_main(PyThreadState *tstate) 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"); } status = init_importlib_external(tstate); @@ -1031,6 +1042,8 @@ init_interp_main(PyThreadState *tstate) #endif } + assert(!_PyErr_Occurred(tstate)); + return _PyStatus_OK(); } @@ -1534,70 +1547,40 @@ new_interpreter(PyThreadState **tstate_p) status = _PyConfig_Copy(&interp->config, config); if (_PyStatus_EXCEPTION(status)) { - goto done; + goto error; } config = &interp->config; status = pycore_init_types(tstate); - - /* XXX The following is lax in error checking */ - PyObject *modules = PyDict_New(); - if (modules == NULL) { - status = _PyStatus_ERR("can't make modules dictionary"); - goto done; + if (_PyStatus_EXCEPTION(status)) { + goto error; } - interp->modules = modules; - PyObject *sysmod = _PyImport_FindBuiltin(tstate, "sys"); - if (sysmod != NULL) { - interp->sysdict = PyModule_GetDict(sysmod); - if (interp->sysdict == NULL) { - goto handle_exc; - } - Py_INCREF(interp->sysdict); - PyDict_SetItemString(interp->sysdict, "modules", modules); - if (_PySys_InitMain(tstate) < 0) { - status = _PyStatus_ERR("can't finish initializing sys"); - goto done; - } - } - else if (_PyErr_Occurred(tstate)) { - goto handle_exc; + PyObject *sysmod; + status = _PySys_Create(tstate, &sysmod); + if (_PyStatus_EXCEPTION(status)) { + return status; } status = pycore_init_builtins(tstate); if (_PyStatus_EXCEPTION(status)) { - goto done; + goto error; } - if (sysmod != NULL) { - status = _PySys_SetPreliminaryStderr(interp->sysdict); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - status = pycore_init_import_warnings(tstate, sysmod); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } - - status = init_interp_main(tstate); - if (_PyStatus_EXCEPTION(status)) { - goto done; - } + status = pycore_init_import_warnings(tstate, sysmod); + if (_PyStatus_EXCEPTION(status)) { + goto error; } - if (_PyErr_Occurred(tstate)) { - goto handle_exc; + status = init_interp_main(tstate); + if (_PyStatus_EXCEPTION(status)) { + goto error; } *tstate_p = tstate; return _PyStatus_OK(); -handle_exc: - status = _PyStatus_OK(); - -done: +error: *tstate_p = NULL; /* Oops, it didn't work. Undo it all. */ diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 78b9d22821f..b6bdf51bce3 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -2919,7 +2919,7 @@ _PySys_InitMain(PyThreadState *tstate) infrastructure for the io module in place. Use UTF-8/surrogateescape and ignore EAGAIN errors. */ -PyStatus +static PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict) { PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr)); @@ -2946,11 +2946,13 @@ _PySys_SetPreliminaryStderr(PyObject *sysdict) PyStatus _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p) { + assert(!_PyErr_Occurred(tstate)); + PyInterpreterState *interp = tstate->interp; PyObject *modules = PyDict_New(); if (modules == NULL) { - return _PyStatus_ERR("can't make modules dictionary"); + goto error; } interp->modules = modules; @@ -2961,13 +2963,13 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p) PyObject *sysdict = PyModule_GetDict(sysmod); if (sysdict == NULL) { - return _PyStatus_ERR("can't initialize sys dict"); + goto error; } Py_INCREF(sysdict); interp->sysdict = sysdict; if (PyDict_SetItemString(sysdict, "modules", interp->modules) < 0) { - return _PyStatus_ERR("can't initialize sys module"); + goto error; } PyStatus status = _PySys_SetPreliminaryStderr(sysdict); @@ -2980,10 +2982,17 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p) return status; } - _PyImport_FixupBuiltin(sysmod, "sys", interp->modules); + if (_PyImport_FixupBuiltin(sysmod, "sys", interp->modules) < 0) { + goto error; + } + + assert(!_PyErr_Occurred(tstate)); *sysmod_p = sysmod; return _PyStatus_OK(); + +error: + return _PyStatus_ERR("can't initialize sys module"); }