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