@@ -666,6 +666,82 @@ struct PyModuleDef _PyIO_Module = {
666
666
(freefunc )iomodule_free ,
667
667
};
668
668
669
+
670
+ static PyTypeObject * static_types [] = {
671
+ // Base classes
672
+ & PyIOBase_Type ,
673
+ & PyIncrementalNewlineDecoder_Type ,
674
+
675
+ // PyIOBase_Type subclasses
676
+ & PyBufferedIOBase_Type ,
677
+ & PyRawIOBase_Type ,
678
+ & PyTextIOBase_Type ,
679
+
680
+ // PyBufferedIOBase_Type(PyIOBase_Type) subclasses
681
+ & PyBytesIO_Type ,
682
+ & PyBufferedReader_Type ,
683
+ & PyBufferedWriter_Type ,
684
+ & PyBufferedRWPair_Type ,
685
+ & PyBufferedRandom_Type ,
686
+
687
+ // PyRawIOBase_Type(PyIOBase_Type) subclasses
688
+ & PyFileIO_Type ,
689
+ & _PyBytesIOBuffer_Type ,
690
+ #ifdef MS_WINDOWS
691
+ & PyWindowsConsoleIO_Type ,
692
+ #endif
693
+
694
+ // PyTextIOBase_Type(PyIOBase_Type) subclasses
695
+ & PyStringIO_Type ,
696
+ & PyTextIOWrapper_Type ,
697
+ };
698
+
699
+
700
+ void
701
+ _PyIO_Fini (void )
702
+ {
703
+ for (Py_ssize_t i = Py_ARRAY_LENGTH (static_types ) - 1 ; i >= 0 ; i -- ) {
704
+ PyTypeObject * exc = static_types [i ];
705
+ _PyStaticType_Dealloc (exc );
706
+ }
707
+
708
+ /* Interned strings */
709
+ #define CLEAR_INTERNED (name ) \
710
+ Py_CLEAR(_PyIO_str_ ## name)
711
+
712
+ CLEAR_INTERNED (close );
713
+ CLEAR_INTERNED (closed );
714
+ CLEAR_INTERNED (decode );
715
+ CLEAR_INTERNED (encode );
716
+ CLEAR_INTERNED (fileno );
717
+ CLEAR_INTERNED (flush );
718
+ CLEAR_INTERNED (getstate );
719
+ CLEAR_INTERNED (isatty );
720
+ CLEAR_INTERNED (locale );
721
+ CLEAR_INTERNED (newlines );
722
+ CLEAR_INTERNED (peek );
723
+ CLEAR_INTERNED (read );
724
+ CLEAR_INTERNED (read1 );
725
+ CLEAR_INTERNED (readable );
726
+ CLEAR_INTERNED (readall );
727
+ CLEAR_INTERNED (readinto );
728
+ CLEAR_INTERNED (readline );
729
+ CLEAR_INTERNED (reset );
730
+ CLEAR_INTERNED (seek );
731
+ CLEAR_INTERNED (seekable );
732
+ CLEAR_INTERNED (setstate );
733
+ CLEAR_INTERNED (tell );
734
+ CLEAR_INTERNED (truncate );
735
+ CLEAR_INTERNED (write );
736
+ CLEAR_INTERNED (writable );
737
+ #undef CLEAR_INTERNED
738
+
739
+ Py_CLEAR (_PyIO_str_nl );
740
+ Py_CLEAR (_PyIO_empty_str );
741
+ Py_CLEAR (_PyIO_empty_bytes );
742
+ }
743
+
744
+
669
745
PyMODINIT_FUNC
670
746
PyInit__io (void )
671
747
{
@@ -676,11 +752,6 @@ PyInit__io(void)
676
752
state = get_io_state (m );
677
753
state -> initialized = 0 ;
678
754
679
- #define ADD_TYPE (type ) \
680
- if (PyModule_AddType(m, type) < 0) { \
681
- goto fail; \
682
- }
683
-
684
755
/* DEFAULT_BUFFER_SIZE */
685
756
if (PyModule_AddIntMacro (m , DEFAULT_BUFFER_SIZE ) < 0 )
686
757
goto fail ;
@@ -702,57 +773,34 @@ PyInit__io(void)
702
773
(PyObject * ) PyExc_BlockingIOError ) < 0 )
703
774
goto fail ;
704
775
705
- /* Concrete base types of the IO ABCs.
706
- (the ABCs themselves are declared through inheritance in io.py)
707
- */
708
- ADD_TYPE (& PyIOBase_Type );
709
- ADD_TYPE (& PyRawIOBase_Type );
710
- ADD_TYPE (& PyBufferedIOBase_Type );
711
- ADD_TYPE (& PyTextIOBase_Type );
712
-
713
- /* Implementation of concrete IO objects. */
714
- /* FileIO */
776
+ // Set type base classes
715
777
PyFileIO_Type .tp_base = & PyRawIOBase_Type ;
716
- ADD_TYPE (& PyFileIO_Type );
717
-
718
- /* BytesIO */
719
778
PyBytesIO_Type .tp_base = & PyBufferedIOBase_Type ;
720
- ADD_TYPE (& PyBytesIO_Type );
721
- if (PyType_Ready (& _PyBytesIOBuffer_Type ) < 0 )
722
- goto fail ;
723
-
724
- /* StringIO */
725
779
PyStringIO_Type .tp_base = & PyTextIOBase_Type ;
726
- ADD_TYPE (& PyStringIO_Type );
727
-
728
780
#ifdef MS_WINDOWS
729
- /* WindowsConsoleIO */
730
781
PyWindowsConsoleIO_Type .tp_base = & PyRawIOBase_Type ;
731
- ADD_TYPE (& PyWindowsConsoleIO_Type );
732
782
#endif
733
-
734
- /* BufferedReader */
735
783
PyBufferedReader_Type .tp_base = & PyBufferedIOBase_Type ;
736
- ADD_TYPE (& PyBufferedReader_Type );
737
-
738
- /* BufferedWriter */
739
784
PyBufferedWriter_Type .tp_base = & PyBufferedIOBase_Type ;
740
- ADD_TYPE (& PyBufferedWriter_Type );
741
-
742
- /* BufferedRWPair */
743
785
PyBufferedRWPair_Type .tp_base = & PyBufferedIOBase_Type ;
744
- ADD_TYPE (& PyBufferedRWPair_Type );
745
-
746
- /* BufferedRandom */
747
786
PyBufferedRandom_Type .tp_base = & PyBufferedIOBase_Type ;
748
- ADD_TYPE (& PyBufferedRandom_Type );
749
-
750
- /* TextIOWrapper */
751
787
PyTextIOWrapper_Type .tp_base = & PyTextIOBase_Type ;
752
- ADD_TYPE (& PyTextIOWrapper_Type );
753
788
754
- /* IncrementalNewlineDecoder */
755
- ADD_TYPE (& PyIncrementalNewlineDecoder_Type );
789
+ // Add types
790
+ for (size_t i = 0 ; i < Py_ARRAY_LENGTH (static_types ); i ++ ) {
791
+ PyTypeObject * type = static_types [i ];
792
+ // Private type not exposed in the _io module
793
+ if (type == & _PyBytesIOBuffer_Type ) {
794
+ if (PyType_Ready (type ) < 0 ) {
795
+ goto fail ;
796
+ }
797
+ }
798
+ else {
799
+ if (PyModule_AddType (m , type ) < 0 ) {
800
+ goto fail ;
801
+ }
802
+ }
803
+ }
756
804
757
805
/* Interned strings */
758
806
#define ADD_INTERNED (name ) \
@@ -785,6 +833,7 @@ PyInit__io(void)
785
833
ADD_INTERNED (truncate )
786
834
ADD_INTERNED (write )
787
835
ADD_INTERNED (writable )
836
+ #undef ADD_INTERNED
788
837
789
838
if (!_PyIO_str_nl &&
790
839
!(_PyIO_str_nl = PyUnicode_InternFromString ("\n ")))
0 commit comments