(root)/
Python-3.11.7/
Modules/
_io/
_iomodule.c
       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 *
     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 *
     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 *
     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
     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*
     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 *
     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
     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
     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
     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
     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
     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  }