Skip to content

Commit

Permalink
gh-94673: Isolate the _io module to Each Interpreter (gh-102663)
Browse files Browse the repository at this point in the history
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.)

#94673
  • Loading branch information
ericsnowcurrently authored Mar 21, 2023
1 parent 8d015fa commit e6ecd3e
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 12 deletions.
40 changes: 32 additions & 8 deletions Modules/_io/_iomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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];
Expand Down
12 changes: 8 additions & 4 deletions Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit e6ecd3e

Please sign in to comment.