1010#define PY_SSIZE_T_CLEAN
1111#include "Python.h"
1212#include "_iomodule.h"
13- #include "pycore_moduleobject.h" // _PyModule_GetState()
1413#include "pycore_pystate.h" // _PyInterpreterState_GET()
1514
1615#ifdef HAVE_SYS_TYPES_H
@@ -315,8 +314,9 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
315314 }
316315
317316 /* Create the Raw file stream */
317+ _PyIO_State *state = get_io_state(module);
318318 {
319- PyObject *RawIO_class = (PyObject *)& PyFileIO_Type;
319+ PyObject *RawIO_class = (PyObject *)state-> PyFileIO_Type;
320320#ifdef MS_WINDOWS
321321 const PyConfig *config = _Py_GetConfig();
322322 if (!config->legacy_windows_stdio && _PyIO_get_console_type(path_or_fd) != '\0') {
@@ -390,12 +390,15 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
390390 {
391391 PyObject *Buffered_class;
392392
393- if (updating)
394- Buffered_class = (PyObject *)&PyBufferedRandom_Type;
395- else if (creating || writing || appending)
396- Buffered_class = (PyObject *)&PyBufferedWriter_Type;
397- else if (reading)
398- Buffered_class = (PyObject *)&PyBufferedReader_Type;
393+ if (updating) {
394+ Buffered_class = (PyObject *)state->PyBufferedRandom_Type;
395+ }
396+ else if (creating || writing || appending) {
397+ Buffered_class = (PyObject *)state->PyBufferedWriter_Type;
398+ }
399+ else if (reading) {
400+ Buffered_class = (PyObject *)state->PyBufferedReader_Type;
401+ }
399402 else {
400403 PyErr_Format(PyExc_ValueError,
401404 "unknown mode: '%s'", mode);
@@ -417,7 +420,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
417420 }
418421
419422 /* wraps into a TextIOWrapper */
420- wrapper = PyObject_CallFunction((PyObject *)& PyTextIOWrapper_Type,
423+ wrapper = PyObject_CallFunction((PyObject *)state-> PyTextIOWrapper_Type,
421424 "OsssO",
422425 buffer,
423426 encoding, errors, newline,
@@ -558,14 +561,6 @@ PyNumber_AsOff_t(PyObject *item, PyObject *err)
558561 return result;
559562}
560563
561- static inline _PyIO_State*
562- get_io_state(PyObject *module)
563- {
564- void *state = _PyModule_GetState(module);
565- assert(state != NULL);
566- return (_PyIO_State *)state;
567- }
568-
569564_PyIO_State *
570565_PyIO_get_module_state(void)
571566{
@@ -587,6 +582,15 @@ iomodule_traverse(PyObject *mod, visitproc visit, void *arg) {
587582 return 0;
588583 Py_VISIT(state->locale_module);
589584 Py_VISIT(state->unsupported_operation);
585+
586+ Py_VISIT(state->PyBufferedRWPair_Type);
587+ Py_VISIT(state->PyBufferedRandom_Type);
588+ Py_VISIT(state->PyBufferedReader_Type);
589+ Py_VISIT(state->PyBufferedWriter_Type);
590+ Py_VISIT(state->PyBytesIO_Type);
591+ Py_VISIT(state->PyFileIO_Type);
592+ Py_VISIT(state->PyStringIO_Type);
593+ Py_VISIT(state->PyTextIOWrapper_Type);
590594 return 0;
591595}
592596
@@ -599,6 +603,15 @@ iomodule_clear(PyObject *mod) {
599603 if (state->locale_module != NULL)
600604 Py_CLEAR(state->locale_module);
601605 Py_CLEAR(state->unsupported_operation);
606+
607+ Py_CLEAR(state->PyBufferedRWPair_Type);
608+ Py_CLEAR(state->PyBufferedRandom_Type);
609+ Py_CLEAR(state->PyBufferedReader_Type);
610+ Py_CLEAR(state->PyBufferedWriter_Type);
611+ Py_CLEAR(state->PyBytesIO_Type);
612+ Py_CLEAR(state->PyFileIO_Type);
613+ Py_CLEAR(state->PyStringIO_Type);
614+ Py_CLEAR(state->PyTextIOWrapper_Type);
602615 return 0;
603616}
604617
@@ -612,7 +625,9 @@ iomodule_free(PyObject *mod) {
612625 * Module definition
613626 */
614627
628+ #define clinic_state() (get_io_state(module))
615629#include "clinic/_iomodule.c.h"
630+ #undef clinic_state
616631
617632static PyMethodDef module_methods[] = {
618633 _IO_OPEN_METHODDEF
@@ -644,23 +659,11 @@ static PyTypeObject* static_types[] = {
644659 &PyRawIOBase_Type,
645660 &PyTextIOBase_Type,
646661
647- // PyBufferedIOBase_Type(PyIOBase_Type) subclasses
648- &PyBytesIO_Type,
649- &PyBufferedReader_Type,
650- &PyBufferedWriter_Type,
651- &PyBufferedRWPair_Type,
652- &PyBufferedRandom_Type,
653-
654662 // PyRawIOBase_Type(PyIOBase_Type) subclasses
655- &PyFileIO_Type,
656663 &_PyBytesIOBuffer_Type,
657664#ifdef MS_WINDOWS
658665 &PyWindowsConsoleIO_Type,
659666#endif
660-
661- // PyTextIOBase_Type(PyIOBase_Type) subclasses
662- &PyStringIO_Type,
663- &PyTextIOWrapper_Type,
664667};
665668
666669
@@ -673,6 +676,17 @@ _PyIO_Fini(void)
673676 }
674677}
675678
679+ #define ADD_TYPE(module, type, spec, base) \
680+ do { \
681+ type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, \
682+ (PyObject *)base); \
683+ if (type == NULL) { \
684+ goto fail; \
685+ } \
686+ if (PyModule_AddType(module, type) < 0) { \
687+ goto fail; \
688+ } \
689+ } while (0)
676690
677691PyMODINIT_FUNC
678692PyInit__io(void)
@@ -705,17 +719,9 @@ PyInit__io(void)
705719 }
706720
707721 // Set type base classes
708- PyFileIO_Type.tp_base = &PyRawIOBase_Type;
709- PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type;
710- PyStringIO_Type.tp_base = &PyTextIOBase_Type;
711722#ifdef MS_WINDOWS
712723 PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
713724#endif
714- PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type;
715- PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type;
716- PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type;
717- PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type;
718- PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type;
719725
720726 // Add types
721727 for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
@@ -725,6 +731,25 @@ PyInit__io(void)
725731 }
726732 }
727733
734+ // PyBufferedIOBase_Type(PyIOBase_Type) subclasses
735+ ADD_TYPE(m, state->PyBytesIO_Type, &bytesio_spec, &PyBufferedIOBase_Type);
736+ ADD_TYPE(m, state->PyBufferedWriter_Type, &bufferedwriter_spec,
737+ &PyBufferedIOBase_Type);
738+ ADD_TYPE(m, state->PyBufferedReader_Type, &bufferedreader_spec,
739+ &PyBufferedIOBase_Type);
740+ ADD_TYPE(m, state->PyBufferedRWPair_Type, &bufferedrwpair_spec,
741+ &PyBufferedIOBase_Type);
742+ ADD_TYPE(m, state->PyBufferedRandom_Type, &bufferedrandom_spec,
743+ &PyBufferedIOBase_Type);
744+
745+ // PyRawIOBase_Type(PyIOBase_Type) subclasses
746+ ADD_TYPE(m, state->PyFileIO_Type, &fileio_spec, &PyRawIOBase_Type);
747+
748+ // PyTextIOBase_Type(PyIOBase_Type) subclasses
749+ ADD_TYPE(m, state->PyStringIO_Type, &stringio_spec, &PyTextIOBase_Type);
750+ ADD_TYPE(m, state->PyTextIOWrapper_Type, &textiowrapper_spec,
751+ &PyTextIOBase_Type);
752+
728753 state->initialized = 1;
729754
730755 return m;
0 commit comments