@@ -386,7 +386,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
386386 return result ;
387387 }
388388
389- _PyIO_State * state = IO_STATE ( );
389+ _PyIO_State * state = get_io_state ( module );
390390 /* wraps into a buffered file */
391391 {
392392 PyObject * Buffered_class ;
@@ -562,53 +562,73 @@ PyNumber_AsOff_t(PyObject *item, PyObject *err)
562562 return result ;
563563}
564564
565- _PyIO_State *
566- _PyIO_get_module_state (void )
567- {
568- PyObject * mod = PyState_FindModule (& _PyIO_Module );
569- _PyIO_State * state ;
570- if (mod == NULL || (state = get_io_state (mod )) == NULL ) {
571- PyErr_SetString (PyExc_RuntimeError ,
572- "could not find io module state "
573- "(interpreter shutdown?)" );
574- return NULL ;
575- }
576- return state ;
577- }
578-
579565static int
580- iomodule_traverse (PyObject * mod , visitproc visit , void * arg ) {
566+ iomodule_traverse (PyObject * mod , visitproc visit , void * arg )
567+ {
581568 _PyIO_State * state = get_io_state (mod );
582- if (!state -> initialized )
583- return 0 ;
584569 Py_VISIT (state -> locale_module );
585570 Py_VISIT (state -> unsupported_operation );
571+
572+ Py_VISIT (state -> PyBufferedIOBase_Type );
573+ Py_VISIT (state -> PyBufferedRWPair_Type );
574+ Py_VISIT (state -> PyBufferedRandom_Type );
575+ Py_VISIT (state -> PyBufferedReader_Type );
576+ Py_VISIT (state -> PyBufferedWriter_Type );
577+ Py_VISIT (state -> PyBytesIOBuffer_Type );
578+ Py_VISIT (state -> PyBytesIO_Type );
579+ Py_VISIT (state -> PyFileIO_Type );
580+ Py_VISIT (state -> PyIOBase_Type );
581+ Py_VISIT (state -> PyIncrementalNewlineDecoder_Type );
582+ Py_VISIT (state -> PyRawIOBase_Type );
583+ Py_VISIT (state -> PyStringIO_Type );
584+ Py_VISIT (state -> PyTextIOBase_Type );
585+ Py_VISIT (state -> PyTextIOWrapper_Type );
586+ #ifdef MS_WINDOWS
587+ Py_VISIT (state -> PyWindowsConsoleIO_Type );
588+ #endif
586589 return 0 ;
587590}
588591
589592
590593static int
591- iomodule_clear (PyObject * mod ) {
594+ iomodule_clear (PyObject * mod )
595+ {
592596 _PyIO_State * state = get_io_state (mod );
593- if (!state -> initialized )
594- return 0 ;
595- if (state -> locale_module != NULL )
596- Py_CLEAR (state -> locale_module );
597+ Py_CLEAR (state -> locale_module );
597598 Py_CLEAR (state -> unsupported_operation );
599+
600+ Py_CLEAR (state -> PyBufferedIOBase_Type );
601+ Py_CLEAR (state -> PyBufferedRWPair_Type );
602+ Py_CLEAR (state -> PyBufferedRandom_Type );
603+ Py_CLEAR (state -> PyBufferedReader_Type );
604+ Py_CLEAR (state -> PyBufferedWriter_Type );
605+ Py_CLEAR (state -> PyBytesIOBuffer_Type );
606+ Py_CLEAR (state -> PyBytesIO_Type );
607+ Py_CLEAR (state -> PyFileIO_Type );
608+ Py_CLEAR (state -> PyIOBase_Type );
609+ Py_CLEAR (state -> PyIncrementalNewlineDecoder_Type );
610+ Py_CLEAR (state -> PyRawIOBase_Type );
611+ Py_CLEAR (state -> PyStringIO_Type );
612+ Py_CLEAR (state -> PyTextIOBase_Type );
613+ Py_CLEAR (state -> PyTextIOWrapper_Type );
614+ #ifdef MS_WINDOWS
615+ Py_CLEAR (state -> PyWindowsConsoleIO_Type );
616+ #endif
598617 return 0 ;
599618}
600619
601620static void
602- iomodule_free (PyObject * mod ) {
603- iomodule_clear (mod );
621+ iomodule_free (void * mod )
622+ {
623+ (void )iomodule_clear (mod );
604624}
605625
606626
607627/*
608628 * Module definition
609629 */
610630
611- #define clinic_state () (IO_STATE( ))
631+ #define clinic_state () (get_io_state(module ))
612632#include "clinic/_iomodule.c.h"
613633#undef clinic_state
614634
@@ -619,59 +639,48 @@ static PyMethodDef module_methods[] = {
619639 {NULL , NULL }
620640};
621641
622- struct PyModuleDef _PyIO_Module = {
623- .m_base = PyModuleDef_HEAD_INIT ,
624- .m_name = "io" ,
625- .m_doc = module_doc ,
626- .m_size = sizeof (_PyIO_State ),
627- .m_methods = module_methods ,
628- .m_traverse = iomodule_traverse ,
629- .m_clear = iomodule_clear ,
630- .m_free = iomodule_free ,
631- };
632-
633- #define ADD_TYPE (module , type , spec , base ) \
634- do { \
635- type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, \
636- (PyObject *)base); \
637- if (type == NULL) { \
638- goto fail; \
639- } \
640- if (PyModule_AddType(module, type) < 0) { \
641- goto fail; \
642- } \
643- } while (0)
644-
645- PyMODINIT_FUNC
646- PyInit__io (void )
642+ static int
643+ iomodule_exec (PyObject * m )
647644{
648- PyObject * m = PyModule_Create (& _PyIO_Module );
649- _PyIO_State * state = NULL ;
650- if (m == NULL )
651- return NULL ;
652- state = get_io_state (m );
653- state -> initialized = 0 ;
645+ _PyIO_State * state = get_io_state (m );
654646
655647 /* DEFAULT_BUFFER_SIZE */
656- if (PyModule_AddIntMacro (m , DEFAULT_BUFFER_SIZE ) < 0 )
657- goto fail ;
648+ if (PyModule_AddIntMacro (m , DEFAULT_BUFFER_SIZE ) < 0 ) {
649+ return -1 ;
650+ }
658651
659652 /* UnsupportedOperation inherits from ValueError and OSError */
660653 state -> unsupported_operation = PyObject_CallFunction (
661654 (PyObject * )& PyType_Type , "s(OO){}" ,
662655 "UnsupportedOperation" , PyExc_OSError , PyExc_ValueError );
663- if (state -> unsupported_operation == NULL )
664- goto fail ;
656+ if (state -> unsupported_operation == NULL ) {
657+ return -1 ;
658+ }
665659 if (PyModule_AddObject (m , "UnsupportedOperation" ,
666660 Py_NewRef (state -> unsupported_operation )) < 0 )
667- goto fail ;
661+ {
662+ return -1 ;
663+ }
668664
669665 /* BlockingIOError, for compatibility */
670666 if (PyModule_AddObjectRef (m , "BlockingIOError" ,
671- (PyObject * ) PyExc_BlockingIOError ) < 0 ) {
672- goto fail ;
667+ (PyObject * ) PyExc_BlockingIOError ) < 0 )
668+ {
669+ return -1 ;
673670 }
674671
672+ #define ADD_TYPE (module , type , spec , base ) \
673+ do { \
674+ type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, \
675+ (PyObject *)base); \
676+ if (type == NULL) { \
677+ return -1; \
678+ } \
679+ if (PyModule_AddType(module, type) < 0) { \
680+ return -1; \
681+ } \
682+ } while (0)
683+
675684 // Concrete classes
676685 ADD_TYPE (m , state -> PyIncrementalNewlineDecoder_Type , & nldecoder_spec , NULL );
677686
@@ -705,12 +714,30 @@ PyInit__io(void)
705714 ADD_TYPE (m , state -> PyStringIO_Type , & stringio_spec , base );
706715 ADD_TYPE (m , state -> PyTextIOWrapper_Type , & textiowrapper_spec , base );
707716
708- state -> initialized = 1 ;
717+ #undef ADD_TYPE
709718
710- return m ;
719+ return 0 ;
720+ }
711721
712- fail :
713- Py_XDECREF (state -> unsupported_operation );
714- Py_DECREF (m );
715- return NULL ;
722+ static struct PyModuleDef_Slot iomodule_slots [] = {
723+ {Py_mod_exec , iomodule_exec },
724+ {0 , NULL },
725+ };
726+
727+ struct PyModuleDef _PyIO_Module = {
728+ .m_base = PyModuleDef_HEAD_INIT ,
729+ .m_name = "io" ,
730+ .m_doc = module_doc ,
731+ .m_size = sizeof (_PyIO_State ),
732+ .m_methods = module_methods ,
733+ .m_traverse = iomodule_traverse ,
734+ .m_clear = iomodule_clear ,
735+ .m_free = iomodule_free ,
736+ .m_slots = iomodule_slots ,
737+ };
738+
739+ PyMODINIT_FUNC
740+ PyInit__io (void )
741+ {
742+ return PyModuleDef_Init (& _PyIO_Module );
716743}
0 commit comments