10
10
#define PY_SSIZE_T_CLEAN
11
11
#include "Python.h"
12
12
#include "_iomodule.h"
13
- #include "pycore_moduleobject.h" // _PyModule_GetState()
14
13
#include "pycore_pystate.h" // _PyInterpreterState_GET()
15
14
16
15
#ifdef HAVE_SYS_TYPES_H
@@ -315,8 +314,9 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
315
314
}
316
315
317
316
/* Create the Raw file stream */
317
+ _PyIO_State * state = get_io_state (module );
318
318
{
319
- PyObject * RawIO_class = (PyObject * )& PyFileIO_Type ;
319
+ PyObject * RawIO_class = (PyObject * )state -> PyFileIO_Type ;
320
320
#ifdef MS_WINDOWS
321
321
const PyConfig * config = _Py_GetConfig ();
322
322
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,
390
390
{
391
391
PyObject * Buffered_class ;
392
392
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
+ }
399
402
else {
400
403
PyErr_Format (PyExc_ValueError ,
401
404
"unknown mode: '%s'" , mode );
@@ -417,7 +420,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
417
420
}
418
421
419
422
/* wraps into a TextIOWrapper */
420
- wrapper = PyObject_CallFunction ((PyObject * )& PyTextIOWrapper_Type ,
423
+ wrapper = PyObject_CallFunction ((PyObject * )state -> PyTextIOWrapper_Type ,
421
424
"OsssO" ,
422
425
buffer ,
423
426
encoding , errors , newline ,
@@ -558,14 +561,6 @@ PyNumber_AsOff_t(PyObject *item, PyObject *err)
558
561
return result ;
559
562
}
560
563
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
-
569
564
_PyIO_State *
570
565
_PyIO_get_module_state (void )
571
566
{
@@ -587,6 +582,15 @@ iomodule_traverse(PyObject *mod, visitproc visit, void *arg) {
587
582
return 0 ;
588
583
Py_VISIT (state -> locale_module );
589
584
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 );
590
594
return 0 ;
591
595
}
592
596
@@ -599,6 +603,15 @@ iomodule_clear(PyObject *mod) {
599
603
if (state -> locale_module != NULL )
600
604
Py_CLEAR (state -> locale_module );
601
605
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 );
602
615
return 0 ;
603
616
}
604
617
@@ -612,7 +625,9 @@ iomodule_free(PyObject *mod) {
612
625
* Module definition
613
626
*/
614
627
628
+ #define clinic_state () (get_io_state(module))
615
629
#include "clinic/_iomodule.c.h"
630
+ #undef clinic_state
616
631
617
632
static PyMethodDef module_methods [] = {
618
633
_IO_OPEN_METHODDEF
@@ -644,23 +659,11 @@ static PyTypeObject* static_types[] = {
644
659
& PyRawIOBase_Type ,
645
660
& PyTextIOBase_Type ,
646
661
647
- // PyBufferedIOBase_Type(PyIOBase_Type) subclasses
648
- & PyBytesIO_Type ,
649
- & PyBufferedReader_Type ,
650
- & PyBufferedWriter_Type ,
651
- & PyBufferedRWPair_Type ,
652
- & PyBufferedRandom_Type ,
653
-
654
662
// PyRawIOBase_Type(PyIOBase_Type) subclasses
655
- & PyFileIO_Type ,
656
663
& _PyBytesIOBuffer_Type ,
657
664
#ifdef MS_WINDOWS
658
665
& PyWindowsConsoleIO_Type ,
659
666
#endif
660
-
661
- // PyTextIOBase_Type(PyIOBase_Type) subclasses
662
- & PyStringIO_Type ,
663
- & PyTextIOWrapper_Type ,
664
667
};
665
668
666
669
@@ -673,6 +676,17 @@ _PyIO_Fini(void)
673
676
}
674
677
}
675
678
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)
676
690
677
691
PyMODINIT_FUNC
678
692
PyInit__io (void )
@@ -705,17 +719,9 @@ PyInit__io(void)
705
719
}
706
720
707
721
// 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 ;
711
722
#ifdef MS_WINDOWS
712
723
PyWindowsConsoleIO_Type .tp_base = & PyRawIOBase_Type ;
713
724
#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 ;
719
725
720
726
// Add types
721
727
for (size_t i = 0 ; i < Py_ARRAY_LENGTH (static_types ); i ++ ) {
@@ -725,6 +731,25 @@ PyInit__io(void)
725
731
}
726
732
}
727
733
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
+
728
753
state -> initialized = 1 ;
729
754
730
755
return m ;
0 commit comments