1 /*
2     An implementation of the new I/O lib as defined by PEP 3116 - "New I/O"
3 
4     Classes defined here: UnsupportedOperation, BlockingIOError.
5     Functions defined here: open().
6 
7     Mostly written by Amaury Forgeot d'Arc
8 */
9 
10 #define PY_SSIZE_T_CLEAN
11 #include "Python.h"
12 #include "_iomodule.h"
13 #include "pycore_pystate.h"       // _PyInterpreterState_GET()
14 
15 #ifdef HAVE_SYS_TYPES_H
16 #include <sys/types.h>
17 #endif /* HAVE_SYS_TYPES_H */
18 
19 #ifdef HAVE_SYS_STAT_H
20 #include <sys/stat.h>
21 #endif /* HAVE_SYS_STAT_H */
22 
23 #ifdef MS_WINDOWS
24 #include <windows.h>
25 #endif
26 
27 PyDoc_STRVAR(module_doc,
28 "The io module provides the Python interfaces to stream handling. The\n"
29 "builtin open function is defined in this module.\n"
30 "\n"
31 "At the top of the I/O hierarchy is the abstract base class IOBase. It\n"
32 "defines the basic interface to a stream. Note, however, that there is no\n"
33 "separation between reading and writing to streams; implementations are\n"
34 "allowed to raise an OSError if they do not support a given operation.\n"
35 "\n"
36 "Extending IOBase is RawIOBase which deals simply with the reading and\n"
37 "writing of raw bytes to a stream. FileIO subclasses RawIOBase to provide\n"
38 "an interface to OS files.\n"
39 "\n"
40 "BufferedIOBase deals with buffering on a raw byte stream (RawIOBase). Its\n"
41 "subclasses, BufferedWriter, BufferedReader, and BufferedRWPair buffer\n"
42 "streams that are readable, writable, and both respectively.\n"
43 "BufferedRandom provides a buffered interface to random access\n"
44 "streams. BytesIO is a simple stream of in-memory bytes.\n"
45 "\n"
46 "Another IOBase subclass, TextIOBase, deals with the encoding and decoding\n"
47 "of streams into text. TextIOWrapper, which extends it, is a buffered text\n"
48 "interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO\n"
49 "is an in-memory stream for text.\n"
50 "\n"
51 "Argument names are not part of the specification, and only the arguments\n"
52 "of open() are intended to be used as keyword arguments.\n"
53 "\n"
54 "data:\n"
55 "\n"
56 "DEFAULT_BUFFER_SIZE\n"
57 "\n"
58 "   An int containing the default buffer size used by the module's buffered\n"
59 "   I/O classes. open() uses the file's blksize (as obtained by os.stat) if\n"
60 "   possible.\n"
61     );
62 
63 
64 /*
65  * The main open() function
66  */
67 /*[clinic input]
68 module _io
69 
70 _io.open
71     file: object
72     mode: str = "r"
73     buffering: int = -1
74     encoding: str(accept={str, NoneType}) = None
75     errors: str(accept={str, NoneType}) = None
76     newline: str(accept={str, NoneType}) = None
77     closefd: bool(accept={int}) = True
78     opener: object = None
79 
80 Open file and return a stream.  Raise OSError upon failure.
81 
82 file is either a text or byte string giving the name (and the path
83 if the file isn't in the current working directory) of the file to
84 be opened or an integer file descriptor of the file to be
85 wrapped. (If a file descriptor is given, it is closed when the
86 returned I/O object is closed, unless closefd is set to False.)
87 
88 mode is an optional string that specifies the mode in which the file
89 is opened. It defaults to 'r' which means open for reading in text
90 mode.  Other common values are 'w' for writing (truncating the file if
91 it already exists), 'x' for creating and writing to a new file, and
92 'a' for appending (which on some Unix systems, means that all writes
93 append to the end of the file regardless of the current seek position).
94 In text mode, if encoding is not specified the encoding used is platform
95 dependent: locale.getencoding() is called to get the current locale encoding.
96 (For reading and writing raw bytes use binary mode and leave encoding
97 unspecified.) The available modes are:
98 
99 ========= ===============================================================
100 Character Meaning
101 --------- ---------------------------------------------------------------
102 'r'       open for reading (default)
103 'w'       open for writing, truncating the file first
104 'x'       create a new file and open it for writing
105 'a'       open for writing, appending to the end of the file if it exists
106 'b'       binary mode
107 't'       text mode (default)
108 '+'       open a disk file for updating (reading and writing)
109 ========= ===============================================================
110 
111 The default mode is 'rt' (open for reading text). For binary random
112 access, the mode 'w+b' opens and truncates the file to 0 bytes, while
113 'r+b' opens the file without truncation. The 'x' mode implies 'w' and
114 raises an `FileExistsError` if the file already exists.
115 
116 Python distinguishes between files opened in binary and text modes,
117 even when the underlying operating system doesn't. Files opened in
118 binary mode (appending 'b' to the mode argument) return contents as
119 bytes objects without any decoding. In text mode (the default, or when
120 't' is appended to the mode argument), the contents of the file are
121 returned as strings, the bytes having been first decoded using a
122 platform-dependent encoding or using the specified encoding if given.
123 
124 buffering is an optional integer used to set the buffering policy.
125 Pass 0 to switch buffering off (only allowed in binary mode), 1 to select
126 line buffering (only usable in text mode), and an integer > 1 to indicate
127 the size of a fixed-size chunk buffer.  When no buffering argument is
128 given, the default buffering policy works as follows:
129 
130 * Binary files are buffered in fixed-size chunks; the size of the buffer
131   is chosen using a heuristic trying to determine the underlying device's
132   "block size" and falling back on `io.DEFAULT_BUFFER_SIZE`.
133   On many systems, the buffer will typically be 4096 or 8192 bytes long.
134 
135 * "Interactive" text files (files for which isatty() returns True)
136   use line buffering.  Other text files use the policy described above
137   for binary files.
138 
139 encoding is the name of the encoding used to decode or encode the
140 file. This should only be used in text mode. The default encoding is
141 platform dependent, but any encoding supported by Python can be
142 passed.  See the codecs module for the list of supported encodings.
143 
144 errors is an optional string that specifies how encoding errors are to
145 be handled---this argument should not be used in binary mode. Pass
146 'strict' to raise a ValueError exception if there is an encoding error
147 (the default of None has the same effect), or pass 'ignore' to ignore
148 errors. (Note that ignoring encoding errors can lead to data loss.)
149 See the documentation for codecs.register or run 'help(codecs.Codec)'
150 for a list of the permitted encoding error strings.
151 
152 newline controls how universal newlines works (it only applies to text
153 mode). It can be None, '', '\n', '\r', and '\r\n'.  It works as
154 follows:
155 
156 * On input, if newline is None, universal newlines mode is
157   enabled. Lines in the input can end in '\n', '\r', or '\r\n', and
158   these are translated into '\n' before being returned to the
159   caller. If it is '', universal newline mode is enabled, but line
160   endings are returned to the caller untranslated. If it has any of
161   the other legal values, input lines are only terminated by the given
162   string, and the line ending is returned to the caller untranslated.
163 
164 * On output, if newline is None, any '\n' characters written are
165   translated to the system default line separator, os.linesep. If
166   newline is '' or '\n', no translation takes place. If newline is any
167   of the other legal values, any '\n' characters written are translated
168   to the given string.
169 
170 If closefd is False, the underlying file descriptor will be kept open
171 when the file is closed. This does not work when a file name is given
172 and must be True in that case.
173 
174 A custom opener can be used by passing a callable as *opener*. The
175 underlying file descriptor for the file object is then obtained by
176 calling *opener* with (*file*, *flags*). *opener* must return an open
177 file descriptor (passing os.open as *opener* results in functionality
178 similar to passing None).
179 
180 open() returns a file object whose type depends on the mode, and
181 through which the standard file operations such as reading and writing
182 are performed. When open() is used to open a file in a text mode ('w',
183 'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open
184 a file in a binary mode, the returned class varies: in read binary
185 mode, it returns a BufferedReader; in write binary and append binary
186 modes, it returns a BufferedWriter, and in read/write mode, it returns
187 a BufferedRandom.
188 
189 It is also possible to use a string or bytearray as a file for both
190 reading and writing. For strings StringIO can be used like a file
191 opened in a text mode, and for bytes a BytesIO can be used like a file
192 opened in a binary mode.
193 [clinic start generated code]*/
194 
195 static PyObject *
_io_open_impl(PyObject * module,PyObject * file,const char * mode,int buffering,const char * encoding,const char * errors,const char * newline,int closefd,PyObject * opener)196 _io_open_impl(PyObject *module, PyObject *file, const char *mode,
197               int buffering, const char *encoding, const char *errors,
198               const char *newline, int closefd, PyObject *opener)
199 /*[clinic end generated code: output=aefafc4ce2b46dc0 input=5bb37f174cb2fb11]*/
200 {
201     unsigned i;
202 
203     int creating = 0, reading = 0, writing = 0, appending = 0, updating = 0;
204     int text = 0, binary = 0;
205 
206     char rawmode[6], *m;
207     int line_buffering, is_number;
208     long isatty = 0;
209 
210     PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL, *path_or_fd = NULL;
211 
212     is_number = PyNumber_Check(file);
213 
214     if (is_number) {
215         path_or_fd = file;
216         Py_INCREF(path_or_fd);
217     } else {
218         path_or_fd = PyOS_FSPath(file);
219         if (path_or_fd == NULL) {
220             return NULL;
221         }
222     }
223 
224     if (!is_number &&
225         !PyUnicode_Check(path_or_fd) &&
226         !PyBytes_Check(path_or_fd)) {
227         PyErr_Format(PyExc_TypeError, "invalid file: %R", file);
228         goto error;
229     }
230 
231     /* Decode mode */
232     for (i = 0; i < strlen(mode); i++) {
233         char c = mode[i];
234 
235         switch (c) {
236         case 'x':
237             creating = 1;
238             break;
239         case 'r':
240             reading = 1;
241             break;
242         case 'w':
243             writing = 1;
244             break;
245         case 'a':
246             appending = 1;
247             break;
248         case '+':
249             updating = 1;
250             break;
251         case 't':
252             text = 1;
253             break;
254         case 'b':
255             binary = 1;
256             break;
257         default:
258             goto invalid_mode;
259         }
260 
261         /* c must not be duplicated */
262         if (strchr(mode+i+1, c)) {
263           invalid_mode:
264             PyErr_Format(PyExc_ValueError, "invalid mode: '%s'", mode);
265             goto error;
266         }
267 
268     }
269 
270     m = rawmode;
271     if (creating)  *(m++) = 'x';
272     if (reading)   *(m++) = 'r';
273     if (writing)   *(m++) = 'w';
274     if (appending) *(m++) = 'a';
275     if (updating)  *(m++) = '+';
276     *m = '\0';
277 
278     /* Parameters validation */
279     if (text && binary) {
280         PyErr_SetString(PyExc_ValueError,
281                         "can't have text and binary mode at once");
282         goto error;
283     }
284 
285     if (creating + reading + writing + appending > 1) {
286         PyErr_SetString(PyExc_ValueError,
287                         "must have exactly one of create/read/write/append mode");
288         goto error;
289     }
290 
291     if (binary && encoding != NULL) {
292         PyErr_SetString(PyExc_ValueError,
293                         "binary mode doesn't take an encoding argument");
294         goto error;
295     }
296 
297     if (binary && errors != NULL) {
298         PyErr_SetString(PyExc_ValueError,
299                         "binary mode doesn't take an errors argument");
300         goto error;
301     }
302 
303     if (binary && newline != NULL) {
304         PyErr_SetString(PyExc_ValueError,
305                         "binary mode doesn't take a newline argument");
306         goto error;
307     }
308 
309     if (binary && buffering == 1) {
310         if (PyErr_WarnEx(PyExc_RuntimeWarning,
311                          "line buffering (buffering=1) isn't supported in "
312                          "binary mode, the default buffer size will be used",
313                          1) < 0) {
314            goto error;
315         }
316     }
317 
318     /* Create the Raw file stream */
319     {
320         PyObject *RawIO_class = (PyObject *)&PyFileIO_Type;
321 #ifdef MS_WINDOWS
322         const PyConfig *config = _Py_GetConfig();
323         if (!config->legacy_windows_stdio && _PyIO_get_console_type(path_or_fd) != '\0') {
324             RawIO_class = (PyObject *)&PyWindowsConsoleIO_Type;
325             encoding = "utf-8";
326         }
327 #endif
328         raw = PyObject_CallFunction(RawIO_class, "OsOO",
329                                     path_or_fd, rawmode,
330                                     closefd ? Py_True : Py_False,
331                                     opener);
332     }
333 
334     if (raw == NULL)
335         goto error;
336     result = raw;
337 
338     Py_DECREF(path_or_fd);
339     path_or_fd = NULL;
340 
341     modeobj = PyUnicode_FromString(mode);
342     if (modeobj == NULL)
343         goto error;
344 
345     /* buffering */
346     if (buffering < 0) {
347         PyObject *res = PyObject_CallMethodNoArgs(raw, &_Py_ID(isatty));
348         if (res == NULL)
349             goto error;
350         isatty = PyLong_AsLong(res);
351         Py_DECREF(res);
352         if (isatty == -1 && PyErr_Occurred())
353             goto error;
354     }
355 
356     if (buffering == 1 || isatty) {
357         buffering = -1;
358         line_buffering = 1;
359     }
360     else
361         line_buffering = 0;
362 
363     if (buffering < 0) {
364         PyObject *blksize_obj;
365         blksize_obj = PyObject_GetAttr(raw, &_Py_ID(_blksize));
366         if (blksize_obj == NULL)
367             goto error;
368         buffering = PyLong_AsLong(blksize_obj);
369         Py_DECREF(blksize_obj);
370         if (buffering == -1 && PyErr_Occurred())
371             goto error;
372     }
373     if (buffering < 0) {
374         PyErr_SetString(PyExc_ValueError,
375                         "invalid buffering size");
376         goto error;
377     }
378 
379     /* if not buffering, returns the raw file object */
380     if (buffering == 0) {
381         if (!binary) {
382             PyErr_SetString(PyExc_ValueError,
383                             "can't have unbuffered text I/O");
384             goto error;
385         }
386 
387         Py_DECREF(modeobj);
388         return result;
389     }
390 
391     /* wraps into a buffered file */
392     {
393         PyObject *Buffered_class;
394 
395         if (updating)
396             Buffered_class = (PyObject *)&PyBufferedRandom_Type;
397         else if (creating || writing || appending)
398             Buffered_class = (PyObject *)&PyBufferedWriter_Type;
399         else if (reading)
400             Buffered_class = (PyObject *)&PyBufferedReader_Type;
401         else {
402             PyErr_Format(PyExc_ValueError,
403                          "unknown mode: '%s'", mode);
404             goto error;
405         }
406 
407         buffer = PyObject_CallFunction(Buffered_class, "Oi", raw, buffering);
408     }
409     if (buffer == NULL)
410         goto error;
411     result = buffer;
412     Py_DECREF(raw);
413 
414 
415     /* if binary, returns the buffered file */
416     if (binary) {
417         Py_DECREF(modeobj);
418         return result;
419     }
420 
421     /* wraps into a TextIOWrapper */
422     wrapper = PyObject_CallFunction((PyObject *)&PyTextIOWrapper_Type,
423                                     "OsssO",
424                                     buffer,
425                                     encoding, errors, newline,
426                                     line_buffering ? Py_True : Py_False);
427     if (wrapper == NULL)
428         goto error;
429     result = wrapper;
430     Py_DECREF(buffer);
431 
432     if (PyObject_SetAttr(wrapper, &_Py_ID(mode), modeobj) < 0)
433         goto error;
434     Py_DECREF(modeobj);
435     return result;
436 
437   error:
438     if (result != NULL) {
439         PyObject *exc, *val, *tb, *close_result;
440         PyErr_Fetch(&exc, &val, &tb);
441         close_result = PyObject_CallMethodNoArgs(result, &_Py_ID(close));
442         _PyErr_ChainExceptions(exc, val, tb);
443         Py_XDECREF(close_result);
444         Py_DECREF(result);
445     }
446     Py_XDECREF(path_or_fd);
447     Py_XDECREF(modeobj);
448     return NULL;
449 }
450 
451 
452 /*[clinic input]
453 _io.text_encoding
454     encoding: object
455     stacklevel: int = 2
456     /
457 
458 A helper function to choose the text encoding.
459 
460 When encoding is not None, this function returns it.
461 Otherwise, this function returns the default text encoding
462 (i.e. "locale" or "utf-8" depends on UTF-8 mode).
463 
464 This function emits an EncodingWarning if encoding is None and
465 sys.flags.warn_default_encoding is true.
466 
467 This can be used in APIs with an encoding=None parameter.
468 However, please consider using encoding="utf-8" for new APIs.
469 [clinic start generated code]*/
470 
471 static PyObject *
_io_text_encoding_impl(PyObject * module,PyObject * encoding,int stacklevel)472 _io_text_encoding_impl(PyObject *module, PyObject *encoding, int stacklevel)
473 /*[clinic end generated code: output=91b2cfea6934cc0c input=4999aa8b3d90f3d4]*/
474 {
475     if (encoding == NULL || encoding == Py_None) {
476         PyInterpreterState *interp = _PyInterpreterState_GET();
477         if (_PyInterpreterState_GetConfig(interp)->warn_default_encoding) {
478             if (PyErr_WarnEx(PyExc_EncodingWarning,
479                              "'encoding' argument not specified", stacklevel)) {
480                 return NULL;
481             }
482         }
483         const PyPreConfig *preconfig = &_PyRuntime.preconfig;
484         if (preconfig->utf8_mode) {
485             _Py_DECLARE_STR(utf_8, "utf-8");
486             encoding = &_Py_STR(utf_8);
487         }
488         else {
489             encoding = &_Py_ID(locale);
490         }
491     }
492     Py_INCREF(encoding);
493     return encoding;
494 }
495 
496 
497 /*[clinic input]
498 _io.open_code
499 
500     path : unicode
501 
502 Opens the provided file with the intent to import the contents.
503 
504 This may perform extra validation beyond open(), but is otherwise interchangeable
505 with calling open(path, 'rb').
506 
507 [clinic start generated code]*/
508 
509 static PyObject *
_io_open_code_impl(PyObject * module,PyObject * path)510 _io_open_code_impl(PyObject *module, PyObject *path)
511 /*[clinic end generated code: output=2fe4ecbd6f3d6844 input=f5c18e23f4b2ed9f]*/
512 {
513     return PyFile_OpenCodeObject(path);
514 }
515 
516 /*
517  * Private helpers for the io module.
518  */
519 
520 Py_off_t
PyNumber_AsOff_t(PyObject * item,PyObject * err)521 PyNumber_AsOff_t(PyObject *item, PyObject *err)
522 {
523     Py_off_t result;
524     PyObject *runerr;
525     PyObject *value = _PyNumber_Index(item);
526     if (value == NULL)
527         return -1;
528 
529     /* We're done if PyLong_AsSsize_t() returns without error. */
530     result = PyLong_AsOff_t(value);
531     if (result != -1 || !(runerr = PyErr_Occurred()))
532         goto finish;
533 
534     /* Error handling code -- only manage OverflowError differently */
535     if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError))
536         goto finish;
537 
538     PyErr_Clear();
539     /* If no error-handling desired then the default clipping
540        is sufficient.
541      */
542     if (!err) {
543         assert(PyLong_Check(value));
544         /* Whether or not it is less than or equal to
545            zero is determined by the sign of ob_size
546         */
547         if (_PyLong_Sign(value) < 0)
548             result = PY_OFF_T_MIN;
549         else
550             result = PY_OFF_T_MAX;
551     }
552     else {
553         /* Otherwise replace the error with caller's error object. */
554         PyErr_Format(err,
555                      "cannot fit '%.200s' into an offset-sized integer",
556                      Py_TYPE(item)->tp_name);
557     }
558 
559  finish:
560     Py_DECREF(value);
561     return result;
562 }
563 
564 static inline _PyIO_State*
get_io_state(PyObject * module)565 get_io_state(PyObject *module)
566 {
567     void *state = PyModule_GetState(module);
568     assert(state != NULL);
569     return (_PyIO_State *)state;
570 }
571 
572 _PyIO_State *
_PyIO_get_module_state(void)573 _PyIO_get_module_state(void)
574 {
575     PyObject *mod = PyState_FindModule(&_PyIO_Module);
576     _PyIO_State *state;
577     if (mod == NULL || (state = get_io_state(mod)) == NULL) {
578         PyErr_SetString(PyExc_RuntimeError,
579                         "could not find io module state "
580                         "(interpreter shutdown?)");
581         return NULL;
582     }
583     return state;
584 }
585 
586 static int
iomodule_traverse(PyObject * mod,visitproc visit,void * arg)587 iomodule_traverse(PyObject *mod, visitproc visit, void *arg) {
588     _PyIO_State *state = get_io_state(mod);
589     if (!state->initialized)
590         return 0;
591     Py_VISIT(state->locale_module);
592     Py_VISIT(state->unsupported_operation);
593     return 0;
594 }
595 
596 
597 static int
iomodule_clear(PyObject * mod)598 iomodule_clear(PyObject *mod) {
599     _PyIO_State *state = get_io_state(mod);
600     if (!state->initialized)
601         return 0;
602     if (state->locale_module != NULL)
603         Py_CLEAR(state->locale_module);
604     Py_CLEAR(state->unsupported_operation);
605     return 0;
606 }
607 
608 static void
iomodule_free(PyObject * mod)609 iomodule_free(PyObject *mod) {
610     iomodule_clear(mod);
611 }
612 
613 
614 /*
615  * Module definition
616  */
617 
618 #include "clinic/_iomodule.c.h"
619 
620 static PyMethodDef module_methods[] = {
621     _IO_OPEN_METHODDEF
622     _IO_TEXT_ENCODING_METHODDEF
623     _IO_OPEN_CODE_METHODDEF
624     {NULL, NULL}
625 };
626 
627 struct PyModuleDef _PyIO_Module = {
628     PyModuleDef_HEAD_INIT,
629     "io",
630     module_doc,
631     sizeof(_PyIO_State),
632     module_methods,
633     NULL,
634     iomodule_traverse,
635     iomodule_clear,
636     (freefunc)iomodule_free,
637 };
638 
639 
640 static PyTypeObject* static_types[] = {
641     // Base classes
642     &PyIOBase_Type,
643     &PyIncrementalNewlineDecoder_Type,
644 
645     // PyIOBase_Type subclasses
646     &PyBufferedIOBase_Type,
647     &PyRawIOBase_Type,
648     &PyTextIOBase_Type,
649 
650     // PyBufferedIOBase_Type(PyIOBase_Type) subclasses
651     &PyBytesIO_Type,
652     &PyBufferedReader_Type,
653     &PyBufferedWriter_Type,
654     &PyBufferedRWPair_Type,
655     &PyBufferedRandom_Type,
656 
657     // PyRawIOBase_Type(PyIOBase_Type) subclasses
658     &PyFileIO_Type,
659     &_PyBytesIOBuffer_Type,
660 #ifdef MS_WINDOWS
661     &PyWindowsConsoleIO_Type,
662 #endif
663 
664     // PyTextIOBase_Type(PyIOBase_Type) subclasses
665     &PyStringIO_Type,
666     &PyTextIOWrapper_Type,
667 };
668 
669 
670 void
_PyIO_Fini(void)671 _PyIO_Fini(void)
672 {
673     for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types) - 1; i >= 0; i--) {
674         PyTypeObject *exc = static_types[i];
675         _PyStaticType_Dealloc(exc);
676     }
677 }
678 
679 
680 PyMODINIT_FUNC
PyInit__io(void)681 PyInit__io(void)
682 {
683     PyObject *m = PyModule_Create(&_PyIO_Module);
684     _PyIO_State *state = NULL;
685     if (m == NULL)
686         return NULL;
687     state = get_io_state(m);
688     state->initialized = 0;
689 
690     /* DEFAULT_BUFFER_SIZE */
691     if (PyModule_AddIntMacro(m, DEFAULT_BUFFER_SIZE) < 0)
692         goto fail;
693 
694     /* UnsupportedOperation inherits from ValueError and OSError */
695     state->unsupported_operation = PyObject_CallFunction(
696         (PyObject *)&PyType_Type, "s(OO){}",
697         "UnsupportedOperation", PyExc_OSError, PyExc_ValueError);
698     if (state->unsupported_operation == NULL)
699         goto fail;
700     Py_INCREF(state->unsupported_operation);
701     if (PyModule_AddObject(m, "UnsupportedOperation",
702                            state->unsupported_operation) < 0)
703         goto fail;
704 
705     /* BlockingIOError, for compatibility */
706     if (PyModule_AddObjectRef(m, "BlockingIOError",
707                               (PyObject *) PyExc_BlockingIOError) < 0) {
708         goto fail;
709     }
710 
711     // Set type base classes
712     PyFileIO_Type.tp_base = &PyRawIOBase_Type;
713     PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type;
714     PyStringIO_Type.tp_base = &PyTextIOBase_Type;
715 #ifdef MS_WINDOWS
716     PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
717 #endif
718     PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type;
719     PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type;
720     PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type;
721     PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type;
722     PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type;
723 
724     // Add types
725     for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
726         PyTypeObject *type = static_types[i];
727         // Private type not exposed in the _io module
728         if (type == &_PyBytesIOBuffer_Type) {
729             if (PyType_Ready(type) < 0) {
730                 goto fail;
731             }
732         }
733         else {
734             if (PyModule_AddType(m, type) < 0) {
735                 goto fail;
736             }
737         }
738     }
739 
740     state->initialized = 1;
741 
742     return m;
743 
744   fail:
745     Py_XDECREF(state->unsupported_operation);
746     Py_DECREF(m);
747     return NULL;
748 }
749