]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-94673: Isolate the _io module to Each Interpreter (gh-102663)
authorEric Snow <ericsnowcurrently@gmail.com>
Tue, 21 Mar 2023 20:01:38 +0000 (14:01 -0600)
committerGitHub <noreply@github.com>
Tue, 21 Mar 2023 20:01:38 +0000 (14:01 -0600)
Aside from sys and builtins, _io is the only core builtin module that hasn't been ported to multi-phase init.  We may do so later (e.g. gh-101948), but in the meantime we must at least take care of the module's static types properly.  (This came up while working on gh-101660.)

https://github.com/python/cpython/issues/94673

Modules/_io/_iomodule.c
Python/pylifecycle.c

index 1506755427fc0d65fa776185ce9bf1184207f3ee..5644cc05c45800630bc4b4e970d53fa40be06a46 100644 (file)
@@ -11,6 +11,7 @@
 #include "Python.h"
 #include "_iomodule.h"
 #include "pycore_pystate.h"       // _PyInterpreterState_GET()
+#include "pycore_initconfig.h"    // _PyStatus_OK()
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -666,12 +667,40 @@ static PyTypeObject* static_types[] = {
 };
 
 
+PyStatus
+_PyIO_InitTypes(PyInterpreterState *interp)
+{
+    if (!_Py_IsMainInterpreter(interp)) {
+        return _PyStatus_OK();
+    }
+
+    // Set type base classes
+#ifdef HAVE_WINDOWS_CONSOLE_IO
+    PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
+#endif
+
+    for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
+        PyTypeObject *type = static_types[i];
+        if (_PyStaticType_InitBuiltin(type) < 0) {
+            return _PyStatus_ERR("Can't initialize builtin type");
+        }
+    }
+
+    return _PyStatus_OK();
+}
+
 void
-_PyIO_Fini(void)
+_PyIO_FiniTypes(PyInterpreterState *interp)
 {
+    if (!_Py_IsMainInterpreter(interp)) {
+        return;
+    }
+
+    // Deallocate types in the reverse order to deallocate subclasses before
+    // their base classes.
     for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types) - 1; i >= 0; i--) {
-        PyTypeObject *exc = static_types[i];
-        _PyStaticType_Dealloc(exc);
+        PyTypeObject *type = static_types[i];
+        _PyStaticType_Dealloc(type);
     }
 }
 
@@ -717,11 +746,6 @@ PyInit__io(void)
         goto fail;
     }
 
-    // Set type base classes
-#ifdef HAVE_WINDOWS_CONSOLE_IO
-    PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
-#endif
-
     // Add types
     for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
         PyTypeObject *type = static_types[i];
index d0e85519d23464e8e7ce8e4654dbf2dcccfa59e5..8110d94ba17526642c991695f1a746ac32ade289 100644 (file)
@@ -31,7 +31,8 @@
 #include "pycore_unicodeobject.h" // _PyUnicode_InitTypes()
 #include "opcode.h"
 
-extern void _PyIO_Fini(void);
+extern PyStatus _PyIO_InitTypes(PyInterpreterState *interp);
+extern void _PyIO_FiniTypes(PyInterpreterState *interp);
 
 #include <locale.h>               // setlocale()
 #include <stdlib.h>               // getenv()
@@ -697,6 +698,11 @@ pycore_init_types(PyInterpreterState *interp)
         return _PyStatus_ERR("failed to initialize an exception type");
     }
 
+    status = _PyIO_InitTypes(interp);
+    if (_PyStatus_EXCEPTION(status)) {
+        return status;
+    }
+
     status = _PyExc_InitGlobalObjects(interp);
     if (_PyStatus_EXCEPTION(status)) {
         return status;
@@ -1700,9 +1706,7 @@ finalize_interp_clear(PyThreadState *tstate)
     /* Clear interpreter state and all thread states */
     _PyInterpreterState_Clear(tstate);
 
-    if (is_main_interp) {
-        _PyIO_Fini();
-    }
+    _PyIO_FiniTypes(tstate->interp);
 
     /* Clear all loghooks */
     /* Both _PySys_Audit function and users still need PyObject, such as tuple.