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