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(
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);

View file

@ -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. */

View file

@ -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");
}