Coverage Report

Created: 2026-06-14 06:25

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