17db96d56Sopenharmony_ci/*
27db96d56Sopenharmony_ci    An implementation of the new I/O lib as defined by PEP 3116 - "New I/O"
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci    Classes defined here: UnsupportedOperation, BlockingIOError.
57db96d56Sopenharmony_ci    Functions defined here: open().
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci    Mostly written by Amaury Forgeot d'Arc
87db96d56Sopenharmony_ci*/
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN
117db96d56Sopenharmony_ci#include "Python.h"
127db96d56Sopenharmony_ci#include "_iomodule.h"
137db96d56Sopenharmony_ci#include "pycore_pystate.h"       // _PyInterpreterState_GET()
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_ci#ifdef HAVE_SYS_TYPES_H
167db96d56Sopenharmony_ci#include <sys/types.h>
177db96d56Sopenharmony_ci#endif /* HAVE_SYS_TYPES_H */
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_ci#ifdef HAVE_SYS_STAT_H
207db96d56Sopenharmony_ci#include <sys/stat.h>
217db96d56Sopenharmony_ci#endif /* HAVE_SYS_STAT_H */
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_ci#ifdef MS_WINDOWS
247db96d56Sopenharmony_ci#include <windows.h>
257db96d56Sopenharmony_ci#endif
267db96d56Sopenharmony_ci
277db96d56Sopenharmony_ciPyDoc_STRVAR(module_doc,
287db96d56Sopenharmony_ci"The io module provides the Python interfaces to stream handling. The\n"
297db96d56Sopenharmony_ci"builtin open function is defined in this module.\n"
307db96d56Sopenharmony_ci"\n"
317db96d56Sopenharmony_ci"At the top of the I/O hierarchy is the abstract base class IOBase. It\n"
327db96d56Sopenharmony_ci"defines the basic interface to a stream. Note, however, that there is no\n"
337db96d56Sopenharmony_ci"separation between reading and writing to streams; implementations are\n"
347db96d56Sopenharmony_ci"allowed to raise an OSError if they do not support a given operation.\n"
357db96d56Sopenharmony_ci"\n"
367db96d56Sopenharmony_ci"Extending IOBase is RawIOBase which deals simply with the reading and\n"
377db96d56Sopenharmony_ci"writing of raw bytes to a stream. FileIO subclasses RawIOBase to provide\n"
387db96d56Sopenharmony_ci"an interface to OS files.\n"
397db96d56Sopenharmony_ci"\n"
407db96d56Sopenharmony_ci"BufferedIOBase deals with buffering on a raw byte stream (RawIOBase). Its\n"
417db96d56Sopenharmony_ci"subclasses, BufferedWriter, BufferedReader, and BufferedRWPair buffer\n"
427db96d56Sopenharmony_ci"streams that are readable, writable, and both respectively.\n"
437db96d56Sopenharmony_ci"BufferedRandom provides a buffered interface to random access\n"
447db96d56Sopenharmony_ci"streams. BytesIO is a simple stream of in-memory bytes.\n"
457db96d56Sopenharmony_ci"\n"
467db96d56Sopenharmony_ci"Another IOBase subclass, TextIOBase, deals with the encoding and decoding\n"
477db96d56Sopenharmony_ci"of streams into text. TextIOWrapper, which extends it, is a buffered text\n"
487db96d56Sopenharmony_ci"interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO\n"
497db96d56Sopenharmony_ci"is an in-memory stream for text.\n"
507db96d56Sopenharmony_ci"\n"
517db96d56Sopenharmony_ci"Argument names are not part of the specification, and only the arguments\n"
527db96d56Sopenharmony_ci"of open() are intended to be used as keyword arguments.\n"
537db96d56Sopenharmony_ci"\n"
547db96d56Sopenharmony_ci"data:\n"
557db96d56Sopenharmony_ci"\n"
567db96d56Sopenharmony_ci"DEFAULT_BUFFER_SIZE\n"
577db96d56Sopenharmony_ci"\n"
587db96d56Sopenharmony_ci"   An int containing the default buffer size used by the module's buffered\n"
597db96d56Sopenharmony_ci"   I/O classes. open() uses the file's blksize (as obtained by os.stat) if\n"
607db96d56Sopenharmony_ci"   possible.\n"
617db96d56Sopenharmony_ci    );
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ci
647db96d56Sopenharmony_ci/*
657db96d56Sopenharmony_ci * The main open() function
667db96d56Sopenharmony_ci */
677db96d56Sopenharmony_ci/*[clinic input]
687db96d56Sopenharmony_cimodule _io
697db96d56Sopenharmony_ci
707db96d56Sopenharmony_ci_io.open
717db96d56Sopenharmony_ci    file: object
727db96d56Sopenharmony_ci    mode: str = "r"
737db96d56Sopenharmony_ci    buffering: int = -1
747db96d56Sopenharmony_ci    encoding: str(accept={str, NoneType}) = None
757db96d56Sopenharmony_ci    errors: str(accept={str, NoneType}) = None
767db96d56Sopenharmony_ci    newline: str(accept={str, NoneType}) = None
777db96d56Sopenharmony_ci    closefd: bool(accept={int}) = True
787db96d56Sopenharmony_ci    opener: object = None
797db96d56Sopenharmony_ci
807db96d56Sopenharmony_ciOpen file and return a stream.  Raise OSError upon failure.
817db96d56Sopenharmony_ci
827db96d56Sopenharmony_cifile is either a text or byte string giving the name (and the path
837db96d56Sopenharmony_ciif the file isn't in the current working directory) of the file to
847db96d56Sopenharmony_cibe opened or an integer file descriptor of the file to be
857db96d56Sopenharmony_ciwrapped. (If a file descriptor is given, it is closed when the
867db96d56Sopenharmony_cireturned I/O object is closed, unless closefd is set to False.)
877db96d56Sopenharmony_ci
887db96d56Sopenharmony_cimode is an optional string that specifies the mode in which the file
897db96d56Sopenharmony_ciis opened. It defaults to 'r' which means open for reading in text
907db96d56Sopenharmony_cimode.  Other common values are 'w' for writing (truncating the file if
917db96d56Sopenharmony_ciit already exists), 'x' for creating and writing to a new file, and
927db96d56Sopenharmony_ci'a' for appending (which on some Unix systems, means that all writes
937db96d56Sopenharmony_ciappend to the end of the file regardless of the current seek position).
947db96d56Sopenharmony_ciIn text mode, if encoding is not specified the encoding used is platform
957db96d56Sopenharmony_cidependent: locale.getencoding() is called to get the current locale encoding.
967db96d56Sopenharmony_ci(For reading and writing raw bytes use binary mode and leave encoding
977db96d56Sopenharmony_ciunspecified.) The available modes are:
987db96d56Sopenharmony_ci
997db96d56Sopenharmony_ci========= ===============================================================
1007db96d56Sopenharmony_ciCharacter Meaning
1017db96d56Sopenharmony_ci--------- ---------------------------------------------------------------
1027db96d56Sopenharmony_ci'r'       open for reading (default)
1037db96d56Sopenharmony_ci'w'       open for writing, truncating the file first
1047db96d56Sopenharmony_ci'x'       create a new file and open it for writing
1057db96d56Sopenharmony_ci'a'       open for writing, appending to the end of the file if it exists
1067db96d56Sopenharmony_ci'b'       binary mode
1077db96d56Sopenharmony_ci't'       text mode (default)
1087db96d56Sopenharmony_ci'+'       open a disk file for updating (reading and writing)
1097db96d56Sopenharmony_ci========= ===============================================================
1107db96d56Sopenharmony_ci
1117db96d56Sopenharmony_ciThe default mode is 'rt' (open for reading text). For binary random
1127db96d56Sopenharmony_ciaccess, the mode 'w+b' opens and truncates the file to 0 bytes, while
1137db96d56Sopenharmony_ci'r+b' opens the file without truncation. The 'x' mode implies 'w' and
1147db96d56Sopenharmony_ciraises an `FileExistsError` if the file already exists.
1157db96d56Sopenharmony_ci
1167db96d56Sopenharmony_ciPython distinguishes between files opened in binary and text modes,
1177db96d56Sopenharmony_cieven when the underlying operating system doesn't. Files opened in
1187db96d56Sopenharmony_cibinary mode (appending 'b' to the mode argument) return contents as
1197db96d56Sopenharmony_cibytes objects without any decoding. In text mode (the default, or when
1207db96d56Sopenharmony_ci't' is appended to the mode argument), the contents of the file are
1217db96d56Sopenharmony_cireturned as strings, the bytes having been first decoded using a
1227db96d56Sopenharmony_ciplatform-dependent encoding or using the specified encoding if given.
1237db96d56Sopenharmony_ci
1247db96d56Sopenharmony_cibuffering is an optional integer used to set the buffering policy.
1257db96d56Sopenharmony_ciPass 0 to switch buffering off (only allowed in binary mode), 1 to select
1267db96d56Sopenharmony_ciline buffering (only usable in text mode), and an integer > 1 to indicate
1277db96d56Sopenharmony_cithe size of a fixed-size chunk buffer.  When no buffering argument is
1287db96d56Sopenharmony_cigiven, the default buffering policy works as follows:
1297db96d56Sopenharmony_ci
1307db96d56Sopenharmony_ci* Binary files are buffered in fixed-size chunks; the size of the buffer
1317db96d56Sopenharmony_ci  is chosen using a heuristic trying to determine the underlying device's
1327db96d56Sopenharmony_ci  "block size" and falling back on `io.DEFAULT_BUFFER_SIZE`.
1337db96d56Sopenharmony_ci  On many systems, the buffer will typically be 4096 or 8192 bytes long.
1347db96d56Sopenharmony_ci
1357db96d56Sopenharmony_ci* "Interactive" text files (files for which isatty() returns True)
1367db96d56Sopenharmony_ci  use line buffering.  Other text files use the policy described above
1377db96d56Sopenharmony_ci  for binary files.
1387db96d56Sopenharmony_ci
1397db96d56Sopenharmony_ciencoding is the name of the encoding used to decode or encode the
1407db96d56Sopenharmony_cifile. This should only be used in text mode. The default encoding is
1417db96d56Sopenharmony_ciplatform dependent, but any encoding supported by Python can be
1427db96d56Sopenharmony_cipassed.  See the codecs module for the list of supported encodings.
1437db96d56Sopenharmony_ci
1447db96d56Sopenharmony_cierrors is an optional string that specifies how encoding errors are to
1457db96d56Sopenharmony_cibe handled---this argument should not be used in binary mode. Pass
1467db96d56Sopenharmony_ci'strict' to raise a ValueError exception if there is an encoding error
1477db96d56Sopenharmony_ci(the default of None has the same effect), or pass 'ignore' to ignore
1487db96d56Sopenharmony_cierrors. (Note that ignoring encoding errors can lead to data loss.)
1497db96d56Sopenharmony_ciSee the documentation for codecs.register or run 'help(codecs.Codec)'
1507db96d56Sopenharmony_cifor a list of the permitted encoding error strings.
1517db96d56Sopenharmony_ci
1527db96d56Sopenharmony_cinewline controls how universal newlines works (it only applies to text
1537db96d56Sopenharmony_cimode). It can be None, '', '\n', '\r', and '\r\n'.  It works as
1547db96d56Sopenharmony_cifollows:
1557db96d56Sopenharmony_ci
1567db96d56Sopenharmony_ci* On input, if newline is None, universal newlines mode is
1577db96d56Sopenharmony_ci  enabled. Lines in the input can end in '\n', '\r', or '\r\n', and
1587db96d56Sopenharmony_ci  these are translated into '\n' before being returned to the
1597db96d56Sopenharmony_ci  caller. If it is '', universal newline mode is enabled, but line
1607db96d56Sopenharmony_ci  endings are returned to the caller untranslated. If it has any of
1617db96d56Sopenharmony_ci  the other legal values, input lines are only terminated by the given
1627db96d56Sopenharmony_ci  string, and the line ending is returned to the caller untranslated.
1637db96d56Sopenharmony_ci
1647db96d56Sopenharmony_ci* On output, if newline is None, any '\n' characters written are
1657db96d56Sopenharmony_ci  translated to the system default line separator, os.linesep. If
1667db96d56Sopenharmony_ci  newline is '' or '\n', no translation takes place. If newline is any
1677db96d56Sopenharmony_ci  of the other legal values, any '\n' characters written are translated
1687db96d56Sopenharmony_ci  to the given string.
1697db96d56Sopenharmony_ci
1707db96d56Sopenharmony_ciIf closefd is False, the underlying file descriptor will be kept open
1717db96d56Sopenharmony_ciwhen the file is closed. This does not work when a file name is given
1727db96d56Sopenharmony_ciand must be True in that case.
1737db96d56Sopenharmony_ci
1747db96d56Sopenharmony_ciA custom opener can be used by passing a callable as *opener*. The
1757db96d56Sopenharmony_ciunderlying file descriptor for the file object is then obtained by
1767db96d56Sopenharmony_cicalling *opener* with (*file*, *flags*). *opener* must return an open
1777db96d56Sopenharmony_cifile descriptor (passing os.open as *opener* results in functionality
1787db96d56Sopenharmony_cisimilar to passing None).
1797db96d56Sopenharmony_ci
1807db96d56Sopenharmony_ciopen() returns a file object whose type depends on the mode, and
1817db96d56Sopenharmony_cithrough which the standard file operations such as reading and writing
1827db96d56Sopenharmony_ciare performed. When open() is used to open a file in a text mode ('w',
1837db96d56Sopenharmony_ci'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open
1847db96d56Sopenharmony_cia file in a binary mode, the returned class varies: in read binary
1857db96d56Sopenharmony_cimode, it returns a BufferedReader; in write binary and append binary
1867db96d56Sopenharmony_cimodes, it returns a BufferedWriter, and in read/write mode, it returns
1877db96d56Sopenharmony_cia BufferedRandom.
1887db96d56Sopenharmony_ci
1897db96d56Sopenharmony_ciIt is also possible to use a string or bytearray as a file for both
1907db96d56Sopenharmony_cireading and writing. For strings StringIO can be used like a file
1917db96d56Sopenharmony_ciopened in a text mode, and for bytes a BytesIO can be used like a file
1927db96d56Sopenharmony_ciopened in a binary mode.
1937db96d56Sopenharmony_ci[clinic start generated code]*/
1947db96d56Sopenharmony_ci
1957db96d56Sopenharmony_cistatic PyObject *
1967db96d56Sopenharmony_ci_io_open_impl(PyObject *module, PyObject *file, const char *mode,
1977db96d56Sopenharmony_ci              int buffering, const char *encoding, const char *errors,
1987db96d56Sopenharmony_ci              const char *newline, int closefd, PyObject *opener)
1997db96d56Sopenharmony_ci/*[clinic end generated code: output=aefafc4ce2b46dc0 input=5bb37f174cb2fb11]*/
2007db96d56Sopenharmony_ci{
2017db96d56Sopenharmony_ci    unsigned i;
2027db96d56Sopenharmony_ci
2037db96d56Sopenharmony_ci    int creating = 0, reading = 0, writing = 0, appending = 0, updating = 0;
2047db96d56Sopenharmony_ci    int text = 0, binary = 0;
2057db96d56Sopenharmony_ci
2067db96d56Sopenharmony_ci    char rawmode[6], *m;
2077db96d56Sopenharmony_ci    int line_buffering, is_number;
2087db96d56Sopenharmony_ci    long isatty = 0;
2097db96d56Sopenharmony_ci
2107db96d56Sopenharmony_ci    PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL, *path_or_fd = NULL;
2117db96d56Sopenharmony_ci
2127db96d56Sopenharmony_ci    is_number = PyNumber_Check(file);
2137db96d56Sopenharmony_ci
2147db96d56Sopenharmony_ci    if (is_number) {
2157db96d56Sopenharmony_ci        path_or_fd = file;
2167db96d56Sopenharmony_ci        Py_INCREF(path_or_fd);
2177db96d56Sopenharmony_ci    } else {
2187db96d56Sopenharmony_ci        path_or_fd = PyOS_FSPath(file);
2197db96d56Sopenharmony_ci        if (path_or_fd == NULL) {
2207db96d56Sopenharmony_ci            return NULL;
2217db96d56Sopenharmony_ci        }
2227db96d56Sopenharmony_ci    }
2237db96d56Sopenharmony_ci
2247db96d56Sopenharmony_ci    if (!is_number &&
2257db96d56Sopenharmony_ci        !PyUnicode_Check(path_or_fd) &&
2267db96d56Sopenharmony_ci        !PyBytes_Check(path_or_fd)) {
2277db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError, "invalid file: %R", file);
2287db96d56Sopenharmony_ci        goto error;
2297db96d56Sopenharmony_ci    }
2307db96d56Sopenharmony_ci
2317db96d56Sopenharmony_ci    /* Decode mode */
2327db96d56Sopenharmony_ci    for (i = 0; i < strlen(mode); i++) {
2337db96d56Sopenharmony_ci        char c = mode[i];
2347db96d56Sopenharmony_ci
2357db96d56Sopenharmony_ci        switch (c) {
2367db96d56Sopenharmony_ci        case 'x':
2377db96d56Sopenharmony_ci            creating = 1;
2387db96d56Sopenharmony_ci            break;
2397db96d56Sopenharmony_ci        case 'r':
2407db96d56Sopenharmony_ci            reading = 1;
2417db96d56Sopenharmony_ci            break;
2427db96d56Sopenharmony_ci        case 'w':
2437db96d56Sopenharmony_ci            writing = 1;
2447db96d56Sopenharmony_ci            break;
2457db96d56Sopenharmony_ci        case 'a':
2467db96d56Sopenharmony_ci            appending = 1;
2477db96d56Sopenharmony_ci            break;
2487db96d56Sopenharmony_ci        case '+':
2497db96d56Sopenharmony_ci            updating = 1;
2507db96d56Sopenharmony_ci            break;
2517db96d56Sopenharmony_ci        case 't':
2527db96d56Sopenharmony_ci            text = 1;
2537db96d56Sopenharmony_ci            break;
2547db96d56Sopenharmony_ci        case 'b':
2557db96d56Sopenharmony_ci            binary = 1;
2567db96d56Sopenharmony_ci            break;
2577db96d56Sopenharmony_ci        default:
2587db96d56Sopenharmony_ci            goto invalid_mode;
2597db96d56Sopenharmony_ci        }
2607db96d56Sopenharmony_ci
2617db96d56Sopenharmony_ci        /* c must not be duplicated */
2627db96d56Sopenharmony_ci        if (strchr(mode+i+1, c)) {
2637db96d56Sopenharmony_ci          invalid_mode:
2647db96d56Sopenharmony_ci            PyErr_Format(PyExc_ValueError, "invalid mode: '%s'", mode);
2657db96d56Sopenharmony_ci            goto error;
2667db96d56Sopenharmony_ci        }
2677db96d56Sopenharmony_ci
2687db96d56Sopenharmony_ci    }
2697db96d56Sopenharmony_ci
2707db96d56Sopenharmony_ci    m = rawmode;
2717db96d56Sopenharmony_ci    if (creating)  *(m++) = 'x';
2727db96d56Sopenharmony_ci    if (reading)   *(m++) = 'r';
2737db96d56Sopenharmony_ci    if (writing)   *(m++) = 'w';
2747db96d56Sopenharmony_ci    if (appending) *(m++) = 'a';
2757db96d56Sopenharmony_ci    if (updating)  *(m++) = '+';
2767db96d56Sopenharmony_ci    *m = '\0';
2777db96d56Sopenharmony_ci
2787db96d56Sopenharmony_ci    /* Parameters validation */
2797db96d56Sopenharmony_ci    if (text && binary) {
2807db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
2817db96d56Sopenharmony_ci                        "can't have text and binary mode at once");
2827db96d56Sopenharmony_ci        goto error;
2837db96d56Sopenharmony_ci    }
2847db96d56Sopenharmony_ci
2857db96d56Sopenharmony_ci    if (creating + reading + writing + appending > 1) {
2867db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
2877db96d56Sopenharmony_ci                        "must have exactly one of create/read/write/append mode");
2887db96d56Sopenharmony_ci        goto error;
2897db96d56Sopenharmony_ci    }
2907db96d56Sopenharmony_ci
2917db96d56Sopenharmony_ci    if (binary && encoding != NULL) {
2927db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
2937db96d56Sopenharmony_ci                        "binary mode doesn't take an encoding argument");
2947db96d56Sopenharmony_ci        goto error;
2957db96d56Sopenharmony_ci    }
2967db96d56Sopenharmony_ci
2977db96d56Sopenharmony_ci    if (binary && errors != NULL) {
2987db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
2997db96d56Sopenharmony_ci                        "binary mode doesn't take an errors argument");
3007db96d56Sopenharmony_ci        goto error;
3017db96d56Sopenharmony_ci    }
3027db96d56Sopenharmony_ci
3037db96d56Sopenharmony_ci    if (binary && newline != NULL) {
3047db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
3057db96d56Sopenharmony_ci                        "binary mode doesn't take a newline argument");
3067db96d56Sopenharmony_ci        goto error;
3077db96d56Sopenharmony_ci    }
3087db96d56Sopenharmony_ci
3097db96d56Sopenharmony_ci    if (binary && buffering == 1) {
3107db96d56Sopenharmony_ci        if (PyErr_WarnEx(PyExc_RuntimeWarning,
3117db96d56Sopenharmony_ci                         "line buffering (buffering=1) isn't supported in "
3127db96d56Sopenharmony_ci                         "binary mode, the default buffer size will be used",
3137db96d56Sopenharmony_ci                         1) < 0) {
3147db96d56Sopenharmony_ci           goto error;
3157db96d56Sopenharmony_ci        }
3167db96d56Sopenharmony_ci    }
3177db96d56Sopenharmony_ci
3187db96d56Sopenharmony_ci    /* Create the Raw file stream */
3197db96d56Sopenharmony_ci    {
3207db96d56Sopenharmony_ci        PyObject *RawIO_class = (PyObject *)&PyFileIO_Type;
3217db96d56Sopenharmony_ci#ifdef MS_WINDOWS
3227db96d56Sopenharmony_ci        const PyConfig *config = _Py_GetConfig();
3237db96d56Sopenharmony_ci        if (!config->legacy_windows_stdio && _PyIO_get_console_type(path_or_fd) != '\0') {
3247db96d56Sopenharmony_ci            RawIO_class = (PyObject *)&PyWindowsConsoleIO_Type;
3257db96d56Sopenharmony_ci            encoding = "utf-8";
3267db96d56Sopenharmony_ci        }
3277db96d56Sopenharmony_ci#endif
3287db96d56Sopenharmony_ci        raw = PyObject_CallFunction(RawIO_class, "OsOO",
3297db96d56Sopenharmony_ci                                    path_or_fd, rawmode,
3307db96d56Sopenharmony_ci                                    closefd ? Py_True : Py_False,
3317db96d56Sopenharmony_ci                                    opener);
3327db96d56Sopenharmony_ci    }
3337db96d56Sopenharmony_ci
3347db96d56Sopenharmony_ci    if (raw == NULL)
3357db96d56Sopenharmony_ci        goto error;
3367db96d56Sopenharmony_ci    result = raw;
3377db96d56Sopenharmony_ci
3387db96d56Sopenharmony_ci    Py_DECREF(path_or_fd);
3397db96d56Sopenharmony_ci    path_or_fd = NULL;
3407db96d56Sopenharmony_ci
3417db96d56Sopenharmony_ci    modeobj = PyUnicode_FromString(mode);
3427db96d56Sopenharmony_ci    if (modeobj == NULL)
3437db96d56Sopenharmony_ci        goto error;
3447db96d56Sopenharmony_ci
3457db96d56Sopenharmony_ci    /* buffering */
3467db96d56Sopenharmony_ci    if (buffering < 0) {
3477db96d56Sopenharmony_ci        PyObject *res = PyObject_CallMethodNoArgs(raw, &_Py_ID(isatty));
3487db96d56Sopenharmony_ci        if (res == NULL)
3497db96d56Sopenharmony_ci            goto error;
3507db96d56Sopenharmony_ci        isatty = PyLong_AsLong(res);
3517db96d56Sopenharmony_ci        Py_DECREF(res);
3527db96d56Sopenharmony_ci        if (isatty == -1 && PyErr_Occurred())
3537db96d56Sopenharmony_ci            goto error;
3547db96d56Sopenharmony_ci    }
3557db96d56Sopenharmony_ci
3567db96d56Sopenharmony_ci    if (buffering == 1 || isatty) {
3577db96d56Sopenharmony_ci        buffering = -1;
3587db96d56Sopenharmony_ci        line_buffering = 1;
3597db96d56Sopenharmony_ci    }
3607db96d56Sopenharmony_ci    else
3617db96d56Sopenharmony_ci        line_buffering = 0;
3627db96d56Sopenharmony_ci
3637db96d56Sopenharmony_ci    if (buffering < 0) {
3647db96d56Sopenharmony_ci        PyObject *blksize_obj;
3657db96d56Sopenharmony_ci        blksize_obj = PyObject_GetAttr(raw, &_Py_ID(_blksize));
3667db96d56Sopenharmony_ci        if (blksize_obj == NULL)
3677db96d56Sopenharmony_ci            goto error;
3687db96d56Sopenharmony_ci        buffering = PyLong_AsLong(blksize_obj);
3697db96d56Sopenharmony_ci        Py_DECREF(blksize_obj);
3707db96d56Sopenharmony_ci        if (buffering == -1 && PyErr_Occurred())
3717db96d56Sopenharmony_ci            goto error;
3727db96d56Sopenharmony_ci    }
3737db96d56Sopenharmony_ci    if (buffering < 0) {
3747db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
3757db96d56Sopenharmony_ci                        "invalid buffering size");
3767db96d56Sopenharmony_ci        goto error;
3777db96d56Sopenharmony_ci    }
3787db96d56Sopenharmony_ci
3797db96d56Sopenharmony_ci    /* if not buffering, returns the raw file object */
3807db96d56Sopenharmony_ci    if (buffering == 0) {
3817db96d56Sopenharmony_ci        if (!binary) {
3827db96d56Sopenharmony_ci            PyErr_SetString(PyExc_ValueError,
3837db96d56Sopenharmony_ci                            "can't have unbuffered text I/O");
3847db96d56Sopenharmony_ci            goto error;
3857db96d56Sopenharmony_ci        }
3867db96d56Sopenharmony_ci
3877db96d56Sopenharmony_ci        Py_DECREF(modeobj);
3887db96d56Sopenharmony_ci        return result;
3897db96d56Sopenharmony_ci    }
3907db96d56Sopenharmony_ci
3917db96d56Sopenharmony_ci    /* wraps into a buffered file */
3927db96d56Sopenharmony_ci    {
3937db96d56Sopenharmony_ci        PyObject *Buffered_class;
3947db96d56Sopenharmony_ci
3957db96d56Sopenharmony_ci        if (updating)
3967db96d56Sopenharmony_ci            Buffered_class = (PyObject *)&PyBufferedRandom_Type;
3977db96d56Sopenharmony_ci        else if (creating || writing || appending)
3987db96d56Sopenharmony_ci            Buffered_class = (PyObject *)&PyBufferedWriter_Type;
3997db96d56Sopenharmony_ci        else if (reading)
4007db96d56Sopenharmony_ci            Buffered_class = (PyObject *)&PyBufferedReader_Type;
4017db96d56Sopenharmony_ci        else {
4027db96d56Sopenharmony_ci            PyErr_Format(PyExc_ValueError,
4037db96d56Sopenharmony_ci                         "unknown mode: '%s'", mode);
4047db96d56Sopenharmony_ci            goto error;
4057db96d56Sopenharmony_ci        }
4067db96d56Sopenharmony_ci
4077db96d56Sopenharmony_ci        buffer = PyObject_CallFunction(Buffered_class, "Oi", raw, buffering);
4087db96d56Sopenharmony_ci    }
4097db96d56Sopenharmony_ci    if (buffer == NULL)
4107db96d56Sopenharmony_ci        goto error;
4117db96d56Sopenharmony_ci    result = buffer;
4127db96d56Sopenharmony_ci    Py_DECREF(raw);
4137db96d56Sopenharmony_ci
4147db96d56Sopenharmony_ci
4157db96d56Sopenharmony_ci    /* if binary, returns the buffered file */
4167db96d56Sopenharmony_ci    if (binary) {
4177db96d56Sopenharmony_ci        Py_DECREF(modeobj);
4187db96d56Sopenharmony_ci        return result;
4197db96d56Sopenharmony_ci    }
4207db96d56Sopenharmony_ci
4217db96d56Sopenharmony_ci    /* wraps into a TextIOWrapper */
4227db96d56Sopenharmony_ci    wrapper = PyObject_CallFunction((PyObject *)&PyTextIOWrapper_Type,
4237db96d56Sopenharmony_ci                                    "OsssO",
4247db96d56Sopenharmony_ci                                    buffer,
4257db96d56Sopenharmony_ci                                    encoding, errors, newline,
4267db96d56Sopenharmony_ci                                    line_buffering ? Py_True : Py_False);
4277db96d56Sopenharmony_ci    if (wrapper == NULL)
4287db96d56Sopenharmony_ci        goto error;
4297db96d56Sopenharmony_ci    result = wrapper;
4307db96d56Sopenharmony_ci    Py_DECREF(buffer);
4317db96d56Sopenharmony_ci
4327db96d56Sopenharmony_ci    if (PyObject_SetAttr(wrapper, &_Py_ID(mode), modeobj) < 0)
4337db96d56Sopenharmony_ci        goto error;
4347db96d56Sopenharmony_ci    Py_DECREF(modeobj);
4357db96d56Sopenharmony_ci    return result;
4367db96d56Sopenharmony_ci
4377db96d56Sopenharmony_ci  error:
4387db96d56Sopenharmony_ci    if (result != NULL) {
4397db96d56Sopenharmony_ci        PyObject *exc, *val, *tb, *close_result;
4407db96d56Sopenharmony_ci        PyErr_Fetch(&exc, &val, &tb);
4417db96d56Sopenharmony_ci        close_result = PyObject_CallMethodNoArgs(result, &_Py_ID(close));
4427db96d56Sopenharmony_ci        _PyErr_ChainExceptions(exc, val, tb);
4437db96d56Sopenharmony_ci        Py_XDECREF(close_result);
4447db96d56Sopenharmony_ci        Py_DECREF(result);
4457db96d56Sopenharmony_ci    }
4467db96d56Sopenharmony_ci    Py_XDECREF(path_or_fd);
4477db96d56Sopenharmony_ci    Py_XDECREF(modeobj);
4487db96d56Sopenharmony_ci    return NULL;
4497db96d56Sopenharmony_ci}
4507db96d56Sopenharmony_ci
4517db96d56Sopenharmony_ci
4527db96d56Sopenharmony_ci/*[clinic input]
4537db96d56Sopenharmony_ci_io.text_encoding
4547db96d56Sopenharmony_ci    encoding: object
4557db96d56Sopenharmony_ci    stacklevel: int = 2
4567db96d56Sopenharmony_ci    /
4577db96d56Sopenharmony_ci
4587db96d56Sopenharmony_ciA helper function to choose the text encoding.
4597db96d56Sopenharmony_ci
4607db96d56Sopenharmony_ciWhen encoding is not None, this function returns it.
4617db96d56Sopenharmony_ciOtherwise, this function returns the default text encoding
4627db96d56Sopenharmony_ci(i.e. "locale" or "utf-8" depends on UTF-8 mode).
4637db96d56Sopenharmony_ci
4647db96d56Sopenharmony_ciThis function emits an EncodingWarning if encoding is None and
4657db96d56Sopenharmony_cisys.flags.warn_default_encoding is true.
4667db96d56Sopenharmony_ci
4677db96d56Sopenharmony_ciThis can be used in APIs with an encoding=None parameter.
4687db96d56Sopenharmony_ciHowever, please consider using encoding="utf-8" for new APIs.
4697db96d56Sopenharmony_ci[clinic start generated code]*/
4707db96d56Sopenharmony_ci
4717db96d56Sopenharmony_cistatic PyObject *
4727db96d56Sopenharmony_ci_io_text_encoding_impl(PyObject *module, PyObject *encoding, int stacklevel)
4737db96d56Sopenharmony_ci/*[clinic end generated code: output=91b2cfea6934cc0c input=4999aa8b3d90f3d4]*/
4747db96d56Sopenharmony_ci{
4757db96d56Sopenharmony_ci    if (encoding == NULL || encoding == Py_None) {
4767db96d56Sopenharmony_ci        PyInterpreterState *interp = _PyInterpreterState_GET();
4777db96d56Sopenharmony_ci        if (_PyInterpreterState_GetConfig(interp)->warn_default_encoding) {
4787db96d56Sopenharmony_ci            if (PyErr_WarnEx(PyExc_EncodingWarning,
4797db96d56Sopenharmony_ci                             "'encoding' argument not specified", stacklevel)) {
4807db96d56Sopenharmony_ci                return NULL;
4817db96d56Sopenharmony_ci            }
4827db96d56Sopenharmony_ci        }
4837db96d56Sopenharmony_ci        const PyPreConfig *preconfig = &_PyRuntime.preconfig;
4847db96d56Sopenharmony_ci        if (preconfig->utf8_mode) {
4857db96d56Sopenharmony_ci            _Py_DECLARE_STR(utf_8, "utf-8");
4867db96d56Sopenharmony_ci            encoding = &_Py_STR(utf_8);
4877db96d56Sopenharmony_ci        }
4887db96d56Sopenharmony_ci        else {
4897db96d56Sopenharmony_ci            encoding = &_Py_ID(locale);
4907db96d56Sopenharmony_ci        }
4917db96d56Sopenharmony_ci    }
4927db96d56Sopenharmony_ci    Py_INCREF(encoding);
4937db96d56Sopenharmony_ci    return encoding;
4947db96d56Sopenharmony_ci}
4957db96d56Sopenharmony_ci
4967db96d56Sopenharmony_ci
4977db96d56Sopenharmony_ci/*[clinic input]
4987db96d56Sopenharmony_ci_io.open_code
4997db96d56Sopenharmony_ci
5007db96d56Sopenharmony_ci    path : unicode
5017db96d56Sopenharmony_ci
5027db96d56Sopenharmony_ciOpens the provided file with the intent to import the contents.
5037db96d56Sopenharmony_ci
5047db96d56Sopenharmony_ciThis may perform extra validation beyond open(), but is otherwise interchangeable
5057db96d56Sopenharmony_ciwith calling open(path, 'rb').
5067db96d56Sopenharmony_ci
5077db96d56Sopenharmony_ci[clinic start generated code]*/
5087db96d56Sopenharmony_ci
5097db96d56Sopenharmony_cistatic PyObject *
5107db96d56Sopenharmony_ci_io_open_code_impl(PyObject *module, PyObject *path)
5117db96d56Sopenharmony_ci/*[clinic end generated code: output=2fe4ecbd6f3d6844 input=f5c18e23f4b2ed9f]*/
5127db96d56Sopenharmony_ci{
5137db96d56Sopenharmony_ci    return PyFile_OpenCodeObject(path);
5147db96d56Sopenharmony_ci}
5157db96d56Sopenharmony_ci
5167db96d56Sopenharmony_ci/*
5177db96d56Sopenharmony_ci * Private helpers for the io module.
5187db96d56Sopenharmony_ci */
5197db96d56Sopenharmony_ci
5207db96d56Sopenharmony_ciPy_off_t
5217db96d56Sopenharmony_ciPyNumber_AsOff_t(PyObject *item, PyObject *err)
5227db96d56Sopenharmony_ci{
5237db96d56Sopenharmony_ci    Py_off_t result;
5247db96d56Sopenharmony_ci    PyObject *runerr;
5257db96d56Sopenharmony_ci    PyObject *value = _PyNumber_Index(item);
5267db96d56Sopenharmony_ci    if (value == NULL)
5277db96d56Sopenharmony_ci        return -1;
5287db96d56Sopenharmony_ci
5297db96d56Sopenharmony_ci    /* We're done if PyLong_AsSsize_t() returns without error. */
5307db96d56Sopenharmony_ci    result = PyLong_AsOff_t(value);
5317db96d56Sopenharmony_ci    if (result != -1 || !(runerr = PyErr_Occurred()))
5327db96d56Sopenharmony_ci        goto finish;
5337db96d56Sopenharmony_ci
5347db96d56Sopenharmony_ci    /* Error handling code -- only manage OverflowError differently */
5357db96d56Sopenharmony_ci    if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError))
5367db96d56Sopenharmony_ci        goto finish;
5377db96d56Sopenharmony_ci
5387db96d56Sopenharmony_ci    PyErr_Clear();
5397db96d56Sopenharmony_ci    /* If no error-handling desired then the default clipping
5407db96d56Sopenharmony_ci       is sufficient.
5417db96d56Sopenharmony_ci     */
5427db96d56Sopenharmony_ci    if (!err) {
5437db96d56Sopenharmony_ci        assert(PyLong_Check(value));
5447db96d56Sopenharmony_ci        /* Whether or not it is less than or equal to
5457db96d56Sopenharmony_ci           zero is determined by the sign of ob_size
5467db96d56Sopenharmony_ci        */
5477db96d56Sopenharmony_ci        if (_PyLong_Sign(value) < 0)
5487db96d56Sopenharmony_ci            result = PY_OFF_T_MIN;
5497db96d56Sopenharmony_ci        else
5507db96d56Sopenharmony_ci            result = PY_OFF_T_MAX;
5517db96d56Sopenharmony_ci    }
5527db96d56Sopenharmony_ci    else {
5537db96d56Sopenharmony_ci        /* Otherwise replace the error with caller's error object. */
5547db96d56Sopenharmony_ci        PyErr_Format(err,
5557db96d56Sopenharmony_ci                     "cannot fit '%.200s' into an offset-sized integer",
5567db96d56Sopenharmony_ci                     Py_TYPE(item)->tp_name);
5577db96d56Sopenharmony_ci    }
5587db96d56Sopenharmony_ci
5597db96d56Sopenharmony_ci finish:
5607db96d56Sopenharmony_ci    Py_DECREF(value);
5617db96d56Sopenharmony_ci    return result;
5627db96d56Sopenharmony_ci}
5637db96d56Sopenharmony_ci
5647db96d56Sopenharmony_cistatic inline _PyIO_State*
5657db96d56Sopenharmony_ciget_io_state(PyObject *module)
5667db96d56Sopenharmony_ci{
5677db96d56Sopenharmony_ci    void *state = PyModule_GetState(module);
5687db96d56Sopenharmony_ci    assert(state != NULL);
5697db96d56Sopenharmony_ci    return (_PyIO_State *)state;
5707db96d56Sopenharmony_ci}
5717db96d56Sopenharmony_ci
5727db96d56Sopenharmony_ci_PyIO_State *
5737db96d56Sopenharmony_ci_PyIO_get_module_state(void)
5747db96d56Sopenharmony_ci{
5757db96d56Sopenharmony_ci    PyObject *mod = PyState_FindModule(&_PyIO_Module);
5767db96d56Sopenharmony_ci    _PyIO_State *state;
5777db96d56Sopenharmony_ci    if (mod == NULL || (state = get_io_state(mod)) == NULL) {
5787db96d56Sopenharmony_ci        PyErr_SetString(PyExc_RuntimeError,
5797db96d56Sopenharmony_ci                        "could not find io module state "
5807db96d56Sopenharmony_ci                        "(interpreter shutdown?)");
5817db96d56Sopenharmony_ci        return NULL;
5827db96d56Sopenharmony_ci    }
5837db96d56Sopenharmony_ci    return state;
5847db96d56Sopenharmony_ci}
5857db96d56Sopenharmony_ci
5867db96d56Sopenharmony_cistatic int
5877db96d56Sopenharmony_ciiomodule_traverse(PyObject *mod, visitproc visit, void *arg) {
5887db96d56Sopenharmony_ci    _PyIO_State *state = get_io_state(mod);
5897db96d56Sopenharmony_ci    if (!state->initialized)
5907db96d56Sopenharmony_ci        return 0;
5917db96d56Sopenharmony_ci    Py_VISIT(state->locale_module);
5927db96d56Sopenharmony_ci    Py_VISIT(state->unsupported_operation);
5937db96d56Sopenharmony_ci    return 0;
5947db96d56Sopenharmony_ci}
5957db96d56Sopenharmony_ci
5967db96d56Sopenharmony_ci
5977db96d56Sopenharmony_cistatic int
5987db96d56Sopenharmony_ciiomodule_clear(PyObject *mod) {
5997db96d56Sopenharmony_ci    _PyIO_State *state = get_io_state(mod);
6007db96d56Sopenharmony_ci    if (!state->initialized)
6017db96d56Sopenharmony_ci        return 0;
6027db96d56Sopenharmony_ci    if (state->locale_module != NULL)
6037db96d56Sopenharmony_ci        Py_CLEAR(state->locale_module);
6047db96d56Sopenharmony_ci    Py_CLEAR(state->unsupported_operation);
6057db96d56Sopenharmony_ci    return 0;
6067db96d56Sopenharmony_ci}
6077db96d56Sopenharmony_ci
6087db96d56Sopenharmony_cistatic void
6097db96d56Sopenharmony_ciiomodule_free(PyObject *mod) {
6107db96d56Sopenharmony_ci    iomodule_clear(mod);
6117db96d56Sopenharmony_ci}
6127db96d56Sopenharmony_ci
6137db96d56Sopenharmony_ci
6147db96d56Sopenharmony_ci/*
6157db96d56Sopenharmony_ci * Module definition
6167db96d56Sopenharmony_ci */
6177db96d56Sopenharmony_ci
6187db96d56Sopenharmony_ci#include "clinic/_iomodule.c.h"
6197db96d56Sopenharmony_ci
6207db96d56Sopenharmony_cistatic PyMethodDef module_methods[] = {
6217db96d56Sopenharmony_ci    _IO_OPEN_METHODDEF
6227db96d56Sopenharmony_ci    _IO_TEXT_ENCODING_METHODDEF
6237db96d56Sopenharmony_ci    _IO_OPEN_CODE_METHODDEF
6247db96d56Sopenharmony_ci    {NULL, NULL}
6257db96d56Sopenharmony_ci};
6267db96d56Sopenharmony_ci
6277db96d56Sopenharmony_cistruct PyModuleDef _PyIO_Module = {
6287db96d56Sopenharmony_ci    PyModuleDef_HEAD_INIT,
6297db96d56Sopenharmony_ci    "io",
6307db96d56Sopenharmony_ci    module_doc,
6317db96d56Sopenharmony_ci    sizeof(_PyIO_State),
6327db96d56Sopenharmony_ci    module_methods,
6337db96d56Sopenharmony_ci    NULL,
6347db96d56Sopenharmony_ci    iomodule_traverse,
6357db96d56Sopenharmony_ci    iomodule_clear,
6367db96d56Sopenharmony_ci    (freefunc)iomodule_free,
6377db96d56Sopenharmony_ci};
6387db96d56Sopenharmony_ci
6397db96d56Sopenharmony_ci
6407db96d56Sopenharmony_cistatic PyTypeObject* static_types[] = {
6417db96d56Sopenharmony_ci    // Base classes
6427db96d56Sopenharmony_ci    &PyIOBase_Type,
6437db96d56Sopenharmony_ci    &PyIncrementalNewlineDecoder_Type,
6447db96d56Sopenharmony_ci
6457db96d56Sopenharmony_ci    // PyIOBase_Type subclasses
6467db96d56Sopenharmony_ci    &PyBufferedIOBase_Type,
6477db96d56Sopenharmony_ci    &PyRawIOBase_Type,
6487db96d56Sopenharmony_ci    &PyTextIOBase_Type,
6497db96d56Sopenharmony_ci
6507db96d56Sopenharmony_ci    // PyBufferedIOBase_Type(PyIOBase_Type) subclasses
6517db96d56Sopenharmony_ci    &PyBytesIO_Type,
6527db96d56Sopenharmony_ci    &PyBufferedReader_Type,
6537db96d56Sopenharmony_ci    &PyBufferedWriter_Type,
6547db96d56Sopenharmony_ci    &PyBufferedRWPair_Type,
6557db96d56Sopenharmony_ci    &PyBufferedRandom_Type,
6567db96d56Sopenharmony_ci
6577db96d56Sopenharmony_ci    // PyRawIOBase_Type(PyIOBase_Type) subclasses
6587db96d56Sopenharmony_ci    &PyFileIO_Type,
6597db96d56Sopenharmony_ci    &_PyBytesIOBuffer_Type,
6607db96d56Sopenharmony_ci#ifdef MS_WINDOWS
6617db96d56Sopenharmony_ci    &PyWindowsConsoleIO_Type,
6627db96d56Sopenharmony_ci#endif
6637db96d56Sopenharmony_ci
6647db96d56Sopenharmony_ci    // PyTextIOBase_Type(PyIOBase_Type) subclasses
6657db96d56Sopenharmony_ci    &PyStringIO_Type,
6667db96d56Sopenharmony_ci    &PyTextIOWrapper_Type,
6677db96d56Sopenharmony_ci};
6687db96d56Sopenharmony_ci
6697db96d56Sopenharmony_ci
6707db96d56Sopenharmony_civoid
6717db96d56Sopenharmony_ci_PyIO_Fini(void)
6727db96d56Sopenharmony_ci{
6737db96d56Sopenharmony_ci    for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types) - 1; i >= 0; i--) {
6747db96d56Sopenharmony_ci        PyTypeObject *exc = static_types[i];
6757db96d56Sopenharmony_ci        _PyStaticType_Dealloc(exc);
6767db96d56Sopenharmony_ci    }
6777db96d56Sopenharmony_ci}
6787db96d56Sopenharmony_ci
6797db96d56Sopenharmony_ci
6807db96d56Sopenharmony_ciPyMODINIT_FUNC
6817db96d56Sopenharmony_ciPyInit__io(void)
6827db96d56Sopenharmony_ci{
6837db96d56Sopenharmony_ci    PyObject *m = PyModule_Create(&_PyIO_Module);
6847db96d56Sopenharmony_ci    _PyIO_State *state = NULL;
6857db96d56Sopenharmony_ci    if (m == NULL)
6867db96d56Sopenharmony_ci        return NULL;
6877db96d56Sopenharmony_ci    state = get_io_state(m);
6887db96d56Sopenharmony_ci    state->initialized = 0;
6897db96d56Sopenharmony_ci
6907db96d56Sopenharmony_ci    /* DEFAULT_BUFFER_SIZE */
6917db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, DEFAULT_BUFFER_SIZE) < 0)
6927db96d56Sopenharmony_ci        goto fail;
6937db96d56Sopenharmony_ci
6947db96d56Sopenharmony_ci    /* UnsupportedOperation inherits from ValueError and OSError */
6957db96d56Sopenharmony_ci    state->unsupported_operation = PyObject_CallFunction(
6967db96d56Sopenharmony_ci        (PyObject *)&PyType_Type, "s(OO){}",
6977db96d56Sopenharmony_ci        "UnsupportedOperation", PyExc_OSError, PyExc_ValueError);
6987db96d56Sopenharmony_ci    if (state->unsupported_operation == NULL)
6997db96d56Sopenharmony_ci        goto fail;
7007db96d56Sopenharmony_ci    Py_INCREF(state->unsupported_operation);
7017db96d56Sopenharmony_ci    if (PyModule_AddObject(m, "UnsupportedOperation",
7027db96d56Sopenharmony_ci                           state->unsupported_operation) < 0)
7037db96d56Sopenharmony_ci        goto fail;
7047db96d56Sopenharmony_ci
7057db96d56Sopenharmony_ci    /* BlockingIOError, for compatibility */
7067db96d56Sopenharmony_ci    if (PyModule_AddObjectRef(m, "BlockingIOError",
7077db96d56Sopenharmony_ci                              (PyObject *) PyExc_BlockingIOError) < 0) {
7087db96d56Sopenharmony_ci        goto fail;
7097db96d56Sopenharmony_ci    }
7107db96d56Sopenharmony_ci
7117db96d56Sopenharmony_ci    // Set type base classes
7127db96d56Sopenharmony_ci    PyFileIO_Type.tp_base = &PyRawIOBase_Type;
7137db96d56Sopenharmony_ci    PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type;
7147db96d56Sopenharmony_ci    PyStringIO_Type.tp_base = &PyTextIOBase_Type;
7157db96d56Sopenharmony_ci#ifdef MS_WINDOWS
7167db96d56Sopenharmony_ci    PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
7177db96d56Sopenharmony_ci#endif
7187db96d56Sopenharmony_ci    PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type;
7197db96d56Sopenharmony_ci    PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type;
7207db96d56Sopenharmony_ci    PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type;
7217db96d56Sopenharmony_ci    PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type;
7227db96d56Sopenharmony_ci    PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type;
7237db96d56Sopenharmony_ci
7247db96d56Sopenharmony_ci    // Add types
7257db96d56Sopenharmony_ci    for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
7267db96d56Sopenharmony_ci        PyTypeObject *type = static_types[i];
7277db96d56Sopenharmony_ci        // Private type not exposed in the _io module
7287db96d56Sopenharmony_ci        if (type == &_PyBytesIOBuffer_Type) {
7297db96d56Sopenharmony_ci            if (PyType_Ready(type) < 0) {
7307db96d56Sopenharmony_ci                goto fail;
7317db96d56Sopenharmony_ci            }
7327db96d56Sopenharmony_ci        }
7337db96d56Sopenharmony_ci        else {
7347db96d56Sopenharmony_ci            if (PyModule_AddType(m, type) < 0) {
7357db96d56Sopenharmony_ci                goto fail;
7367db96d56Sopenharmony_ci            }
7377db96d56Sopenharmony_ci        }
7387db96d56Sopenharmony_ci    }
7397db96d56Sopenharmony_ci
7407db96d56Sopenharmony_ci    state->initialized = 1;
7417db96d56Sopenharmony_ci
7427db96d56Sopenharmony_ci    return m;
7437db96d56Sopenharmony_ci
7447db96d56Sopenharmony_ci  fail:
7457db96d56Sopenharmony_ci    Py_XDECREF(state->unsupported_operation);
7467db96d56Sopenharmony_ci    Py_DECREF(m);
7477db96d56Sopenharmony_ci    return NULL;
7487db96d56Sopenharmony_ci}
749