(freefunc)iomodule_free,
};
+
+static PyTypeObject* static_types[] = {
+ // Base classes
+ &PyIOBase_Type,
+ &PyIncrementalNewlineDecoder_Type,
+
+ // PyIOBase_Type subclasses
+ &PyBufferedIOBase_Type,
+ &PyRawIOBase_Type,
+ &PyTextIOBase_Type,
+
+ // PyBufferedIOBase_Type(PyIOBase_Type) subclasses
+ &PyBytesIO_Type,
+ &PyBufferedReader_Type,
+ &PyBufferedWriter_Type,
+ &PyBufferedRWPair_Type,
+ &PyBufferedRandom_Type,
+
+ // PyRawIOBase_Type(PyIOBase_Type) subclasses
+ &PyFileIO_Type,
+ &_PyBytesIOBuffer_Type,
+#ifdef MS_WINDOWS
+ &PyWindowsConsoleIO_Type,
+#endif
+
+ // PyTextIOBase_Type(PyIOBase_Type) subclasses
+ &PyStringIO_Type,
+ &PyTextIOWrapper_Type,
+};
+
+
+void
+_PyIO_Fini(void)
+{
+ for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types) - 1; i >= 0; i--) {
+ PyTypeObject *exc = static_types[i];
+ _PyStaticType_Dealloc(exc);
+ }
+
+ /* Interned strings */
+#define CLEAR_INTERNED(name) \
+ Py_CLEAR(_PyIO_str_ ## name)
+
+ CLEAR_INTERNED(close);
+ CLEAR_INTERNED(closed);
+ CLEAR_INTERNED(decode);
+ CLEAR_INTERNED(encode);
+ CLEAR_INTERNED(fileno);
+ CLEAR_INTERNED(flush);
+ CLEAR_INTERNED(getstate);
+ CLEAR_INTERNED(isatty);
+ CLEAR_INTERNED(locale);
+ CLEAR_INTERNED(newlines);
+ CLEAR_INTERNED(peek);
+ CLEAR_INTERNED(read);
+ CLEAR_INTERNED(read1);
+ CLEAR_INTERNED(readable);
+ CLEAR_INTERNED(readall);
+ CLEAR_INTERNED(readinto);
+ CLEAR_INTERNED(readline);
+ CLEAR_INTERNED(reset);
+ CLEAR_INTERNED(seek);
+ CLEAR_INTERNED(seekable);
+ CLEAR_INTERNED(setstate);
+ CLEAR_INTERNED(tell);
+ CLEAR_INTERNED(truncate);
+ CLEAR_INTERNED(write);
+ CLEAR_INTERNED(writable);
+#undef CLEAR_INTERNED
+
+ Py_CLEAR(_PyIO_str_nl);
+ Py_CLEAR(_PyIO_empty_str);
+ Py_CLEAR(_PyIO_empty_bytes);
+}
+
+
PyMODINIT_FUNC
PyInit__io(void)
{
state = get_io_state(m);
state->initialized = 0;
-#define ADD_TYPE(type) \
- if (PyModule_AddType(m, type) < 0) { \
- goto fail; \
- }
-
/* DEFAULT_BUFFER_SIZE */
if (PyModule_AddIntMacro(m, DEFAULT_BUFFER_SIZE) < 0)
goto fail;
(PyObject *) PyExc_BlockingIOError) < 0)
goto fail;
- /* Concrete base types of the IO ABCs.
- (the ABCs themselves are declared through inheritance in io.py)
- */
- ADD_TYPE(&PyIOBase_Type);
- ADD_TYPE(&PyRawIOBase_Type);
- ADD_TYPE(&PyBufferedIOBase_Type);
- ADD_TYPE(&PyTextIOBase_Type);
-
- /* Implementation of concrete IO objects. */
- /* FileIO */
+ // Set type base classes
PyFileIO_Type.tp_base = &PyRawIOBase_Type;
- ADD_TYPE(&PyFileIO_Type);
-
- /* BytesIO */
PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type;
- ADD_TYPE(&PyBytesIO_Type);
- if (PyType_Ready(&_PyBytesIOBuffer_Type) < 0)
- goto fail;
-
- /* StringIO */
PyStringIO_Type.tp_base = &PyTextIOBase_Type;
- ADD_TYPE(&PyStringIO_Type);
-
#ifdef MS_WINDOWS
- /* WindowsConsoleIO */
PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
- ADD_TYPE(&PyWindowsConsoleIO_Type);
#endif
-
- /* BufferedReader */
PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type;
- ADD_TYPE(&PyBufferedReader_Type);
-
- /* BufferedWriter */
PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type;
- ADD_TYPE(&PyBufferedWriter_Type);
-
- /* BufferedRWPair */
PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type;
- ADD_TYPE(&PyBufferedRWPair_Type);
-
- /* BufferedRandom */
PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type;
- ADD_TYPE(&PyBufferedRandom_Type);
-
- /* TextIOWrapper */
PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type;
- ADD_TYPE(&PyTextIOWrapper_Type);
- /* IncrementalNewlineDecoder */
- ADD_TYPE(&PyIncrementalNewlineDecoder_Type);
+ // Add types
+ for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
+ PyTypeObject *type = static_types[i];
+ // Private type not exposed in the _io module
+ if (type == &_PyBytesIOBuffer_Type) {
+ if (PyType_Ready(type) < 0) {
+ goto fail;
+ }
+ }
+ else {
+ if (PyModule_AddType(m, type) < 0) {
+ goto fail;
+ }
+ }
+ }
/* Interned strings */
#define ADD_INTERNED(name) \
ADD_INTERNED(truncate)
ADD_INTERNED(write)
ADD_INTERNED(writable)
+#undef ADD_INTERNED
if (!_PyIO_str_nl &&
!(_PyIO_str_nl = PyUnicode_InternFromString("\n")))