]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-38858: new_interpreter() reuses _PySys_Create() (GH-17481)
authorVictor Stinner <vstinner@python.org>
Fri, 6 Dec 2019 01:43:30 +0000 (02:43 +0100)
committerGitHub <noreply@github.com>
Fri, 6 Dec 2019 01:43:30 +0000 (02:43 +0100)
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
Python/pylifecycle.c
Python/sysmodule.c

index cd3be215ff11245d4bf66fcb6f82e54f2b6fbb3b..4e4bbc2bed098d6961c919bfa46c2f623364059e 100644 (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);
index 410156b80211ec93fff1db17f9e87123025cc224..9822cce4ae3b738a7646c58ccebb4690430682d0 100644 (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 @@ error:
 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. */
index 78b9d22821fe3de87e664d1b0cc3c60bbf8e6935..b6bdf51bce333fd94e634ef937592a71333ecae1 100644 (file)
@@ -2919,7 +2919,7 @@ err_occurred:
    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 @@ error:
 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");
 }