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