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().
This commit is contained in:
Victor Stinner 2019-12-06 02:43:30 +01:00 committed by GitHub
parent 44ea525ca5
commit 81fe5bd3d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 55 deletions

View File

@ -40,7 +40,6 @@ extern PyObject * _PyBuiltin_Init(PyThreadState *tstate);
extern PyStatus _PySys_Create( extern PyStatus _PySys_Create(
PyThreadState *tstate, PyThreadState *tstate,
PyObject **sysmod_p); PyObject **sysmod_p);
extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict);
extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options); extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options);
extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config); extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config);
extern int _PySys_InitMain(PyThreadState *tstate); extern int _PySys_InitMain(PyThreadState *tstate);

View File

@ -622,6 +622,8 @@ pycore_init_types(PyThreadState *tstate)
static PyStatus static PyStatus
pycore_init_builtins(PyThreadState *tstate) pycore_init_builtins(PyThreadState *tstate)
{ {
assert(!_PyErr_Occurred(tstate));
PyObject *bimod = _PyBuiltin_Init(tstate); PyObject *bimod = _PyBuiltin_Init(tstate);
if (bimod == NULL) { if (bimod == NULL) {
goto error; goto error;
@ -649,6 +651,9 @@ pycore_init_builtins(PyThreadState *tstate)
goto error; goto error;
} }
Py_DECREF(bimod); Py_DECREF(bimod);
assert(!_PyErr_Occurred(tstate));
return _PyStatus_OK(); return _PyStatus_OK();
error: error:
@ -660,13 +665,14 @@ pycore_init_builtins(PyThreadState *tstate)
static PyStatus static PyStatus
pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod) pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod)
{ {
const PyConfig *config = &tstate->interp->config; assert(!_PyErr_Occurred(tstate));
PyStatus status = _PyImportHooks_Init(tstate); PyStatus status = _PyImportHooks_Init(tstate);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }
const PyConfig *config = &tstate->interp->config;
if (_Py_IsMainInterpreter(tstate)) { if (_Py_IsMainInterpreter(tstate)) {
/* Initialize _warnings. */ /* Initialize _warnings. */
if (_PyWarnings_Init() == NULL) { if (_PyWarnings_Init() == NULL) {
@ -688,6 +694,9 @@ pycore_init_import_warnings(PyThreadState *tstate, PyObject *sysmod)
return status; return status;
} }
} }
assert(!_PyErr_Occurred(tstate));
return _PyStatus_OK(); return _PyStatus_OK();
} }
@ -929,6 +938,8 @@ _Py_ReconfigureMainInterpreter(PyThreadState *tstate)
static PyStatus static PyStatus
init_interp_main(PyThreadState *tstate) init_interp_main(PyThreadState *tstate)
{ {
assert(!_PyErr_Occurred(tstate));
PyStatus status; PyStatus status;
int is_main_interp = _Py_IsMainInterpreter(tstate); int is_main_interp = _Py_IsMainInterpreter(tstate);
PyInterpreterState *interp = tstate->interp; PyInterpreterState *interp = tstate->interp;
@ -950,11 +961,11 @@ init_interp_main(PyThreadState *tstate)
if (_PyTime_Init() < 0) { if (_PyTime_Init() < 0) {
return _PyStatus_ERR("can't initialize time"); return _PyStatus_ERR("can't initialize time");
} }
}
if (_PySys_InitMain(tstate) < 0) { if (_PySys_InitMain(tstate) < 0) {
return _PyStatus_ERR("can't finish initializing sys"); return _PyStatus_ERR("can't finish initializing sys");
} }
}
status = init_importlib_external(tstate); status = init_importlib_external(tstate);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
@ -1031,6 +1042,8 @@ init_interp_main(PyThreadState *tstate)
#endif #endif
} }
assert(!_PyErr_Occurred(tstate));
return _PyStatus_OK(); return _PyStatus_OK();
} }
@ -1534,70 +1547,40 @@ 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)) {
goto done; goto error;
} }
config = &interp->config; config = &interp->config;
status = pycore_init_types(tstate); status = pycore_init_types(tstate);
if (_PyStatus_EXCEPTION(status)) {
goto error;
}
/* XXX The following is lax in error checking */ PyObject *sysmod;
PyObject *modules = PyDict_New(); status = _PySys_Create(tstate, &sysmod);
if (modules == NULL) { if (_PyStatus_EXCEPTION(status)) {
status = _PyStatus_ERR("can't make modules dictionary"); return status;
goto done;
}
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;
} }
status = pycore_init_builtins(tstate); status = pycore_init_builtins(tstate);
if (_PyStatus_EXCEPTION(status)) { 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); status = pycore_init_import_warnings(tstate, sysmod);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
goto done; goto error;
} }
status = init_interp_main(tstate); status = init_interp_main(tstate);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
goto done; goto error;
}
}
if (_PyErr_Occurred(tstate)) {
goto handle_exc;
} }
*tstate_p = tstate; *tstate_p = tstate;
return _PyStatus_OK(); return _PyStatus_OK();
handle_exc: error:
status = _PyStatus_OK();
done:
*tstate_p = NULL; *tstate_p = NULL;
/* Oops, it didn't work. Undo it all. */ /* Oops, it didn't work. Undo it all. */

View File

@ -2919,7 +2919,7 @@ _PySys_InitMain(PyThreadState *tstate)
infrastructure for the io module in place. infrastructure for the io module in place.
Use UTF-8/surrogateescape and ignore EAGAIN errors. */ Use UTF-8/surrogateescape and ignore EAGAIN errors. */
PyStatus static PyStatus
_PySys_SetPreliminaryStderr(PyObject *sysdict) _PySys_SetPreliminaryStderr(PyObject *sysdict)
{ {
PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr)); PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr));
@ -2946,11 +2946,13 @@ _PySys_SetPreliminaryStderr(PyObject *sysdict)
PyStatus PyStatus
_PySys_Create(PyThreadState *tstate, PyObject **sysmod_p) _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
{ {
assert(!_PyErr_Occurred(tstate));
PyInterpreterState *interp = tstate->interp; PyInterpreterState *interp = tstate->interp;
PyObject *modules = PyDict_New(); PyObject *modules = PyDict_New();
if (modules == NULL) { if (modules == NULL) {
return _PyStatus_ERR("can't make modules dictionary"); goto error;
} }
interp->modules = modules; interp->modules = modules;
@ -2961,13 +2963,13 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
PyObject *sysdict = PyModule_GetDict(sysmod); PyObject *sysdict = PyModule_GetDict(sysmod);
if (sysdict == NULL) { if (sysdict == NULL) {
return _PyStatus_ERR("can't initialize sys dict"); goto error;
} }
Py_INCREF(sysdict); Py_INCREF(sysdict);
interp->sysdict = sysdict; interp->sysdict = sysdict;
if (PyDict_SetItemString(sysdict, "modules", interp->modules) < 0) { if (PyDict_SetItemString(sysdict, "modules", interp->modules) < 0) {
return _PyStatus_ERR("can't initialize sys module"); goto error;
} }
PyStatus status = _PySys_SetPreliminaryStderr(sysdict); PyStatus status = _PySys_SetPreliminaryStderr(sysdict);
@ -2980,10 +2982,17 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p)
return status; 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; *sysmod_p = sysmod;
return _PyStatus_OK(); return _PyStatus_OK();
error:
return _PyStatus_ERR("can't initialize sys module");
} }