Skip to content

Commit 9d7a022

Browse files
ericsnowcurrentlywarsaw
authored andcommitted
pythongh-94673: Isolate the _io module to Each Interpreter (pythongh-102663)
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. pythongh-101948), but in the meantime we must at least take care of the module's static types properly. (This came up while working on pythongh-101660.) python#94673
1 parent 1d16f51 commit 9d7a022

File tree

2 files changed

+40
-12
lines changed

2 files changed

+40
-12
lines changed

Modules/_io/_iomodule.c

+32-8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "Python.h"
1212
#include "_iomodule.h"
1313
#include "pycore_pystate.h" // _PyInterpreterState_GET()
14+
#include "pycore_initconfig.h" // _PyStatus_OK()
1415

1516
#ifdef HAVE_SYS_TYPES_H
1617
#include <sys/types.h>
@@ -666,12 +667,40 @@ static PyTypeObject* static_types[] = {
666667
};
667668

668669

670+
PyStatus
671+
_PyIO_InitTypes(PyInterpreterState *interp)
672+
{
673+
if (!_Py_IsMainInterpreter(interp)) {
674+
return _PyStatus_OK();
675+
}
676+
677+
// Set type base classes
678+
#ifdef HAVE_WINDOWS_CONSOLE_IO
679+
PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
680+
#endif
681+
682+
for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
683+
PyTypeObject *type = static_types[i];
684+
if (_PyStaticType_InitBuiltin(type) < 0) {
685+
return _PyStatus_ERR("Can't initialize builtin type");
686+
}
687+
}
688+
689+
return _PyStatus_OK();
690+
}
691+
669692
void
670-
_PyIO_Fini(void)
693+
_PyIO_FiniTypes(PyInterpreterState *interp)
671694
{
695+
if (!_Py_IsMainInterpreter(interp)) {
696+
return;
697+
}
698+
699+
// Deallocate types in the reverse order to deallocate subclasses before
700+
// their base classes.
672701
for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types) - 1; i >= 0; i--) {
673-
PyTypeObject *exc = static_types[i];
674-
_PyStaticType_Dealloc(exc);
702+
PyTypeObject *type = static_types[i];
703+
_PyStaticType_Dealloc(type);
675704
}
676705
}
677706

@@ -717,11 +746,6 @@ PyInit__io(void)
717746
goto fail;
718747
}
719748

720-
// Set type base classes
721-
#ifdef HAVE_WINDOWS_CONSOLE_IO
722-
PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
723-
#endif
724-
725749
// Add types
726750
for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
727751
PyTypeObject *type = static_types[i];

Python/pylifecycle.c

+8-4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
#include "pycore_unicodeobject.h" // _PyUnicode_InitTypes()
3232
#include "opcode.h"
3333

34-
extern void _PyIO_Fini(void);
34+
extern PyStatus _PyIO_InitTypes(PyInterpreterState *interp);
35+
extern void _PyIO_FiniTypes(PyInterpreterState *interp);
3536

3637
#include <locale.h> // setlocale()
3738
#include <stdlib.h> // getenv()
@@ -697,6 +698,11 @@ pycore_init_types(PyInterpreterState *interp)
697698
return _PyStatus_ERR("failed to initialize an exception type");
698699
}
699700

701+
status = _PyIO_InitTypes(interp);
702+
if (_PyStatus_EXCEPTION(status)) {
703+
return status;
704+
}
705+
700706
status = _PyExc_InitGlobalObjects(interp);
701707
if (_PyStatus_EXCEPTION(status)) {
702708
return status;
@@ -1700,9 +1706,7 @@ finalize_interp_clear(PyThreadState *tstate)
17001706
/* Clear interpreter state and all thread states */
17011707
_PyInterpreterState_Clear(tstate);
17021708

1703-
if (is_main_interp) {
1704-
_PyIO_Fini();
1705-
}
1709+
_PyIO_FiniTypes(tstate->interp);
17061710

17071711
/* Clear all loghooks */
17081712
/* Both _PySys_Audit function and users still need PyObject, such as tuple.

0 commit comments

Comments
 (0)