Coverage Report

Created: 2025-07-11 06:59

/src/Python-3.8.3/Modules/_io/_iomodule.c
Line
Count
Source (jump to first uncovered line)
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
278
{
238
278
    unsigned i;
239
240
278
    int creating = 0, reading = 0, writing = 0, appending = 0, updating = 0;
241
278
    int text = 0, binary = 0, universal = 0;
242
243
278
    char rawmode[6], *m;
244
278
    int line_buffering, is_number;
245
278
    long isatty = 0;
246
247
278
    PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL, *path_or_fd = NULL;
248
249
278
    _Py_IDENTIFIER(_blksize);
250
278
    _Py_IDENTIFIER(isatty);
251
278
    _Py_IDENTIFIER(mode);
252
278
    _Py_IDENTIFIER(close);
253
254
278
    is_number = PyNumber_Check(file);
255
256
278
    if (is_number) {
257
42
        path_or_fd = file;
258
42
        Py_INCREF(path_or_fd);
259
236
    } else {
260
236
        path_or_fd = PyOS_FSPath(file);
261
236
        if (path_or_fd == NULL) {
262
0
            return NULL;
263
0
        }
264
236
    }
265
266
278
    if (!is_number &&
267
278
        !PyUnicode_Check(path_or_fd) &&
268
278
        !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
834
    for (i = 0; i < strlen(mode); i++) {
275
556
        char c = mode[i];
276
277
556
        switch (c) {
278
0
        case 'x':
279
0
            creating = 1;
280
0
            break;
281
250
        case 'r':
282
250
            reading = 1;
283
250
            break;
284
28
        case 'w':
285
28
            writing = 1;
286
28
            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
278
        case 'b':
297
278
            binary = 1;
298
278
            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
556
        }
306
307
        /* c must not be duplicated */
308
556
        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
556
    }
315
316
278
    m = rawmode;
317
278
    if (creating)  *(m++) = 'x';
318
278
    if (reading)   *(m++) = 'r';
319
278
    if (writing)   *(m++) = 'w';
320
278
    if (appending) *(m++) = 'a';
321
278
    if (updating)  *(m++) = '+';
322
278
    *m = '\0';
323
324
    /* Parameters validation */
325
278
    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
278
    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
278
    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
278
    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
278
    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
278
    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
278
    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
278
    {
378
278
        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
278
        raw = PyObject_CallFunction(RawIO_class,
387
278
                                    "OsiO", path_or_fd, rawmode, closefd, opener);
388
278
    }
389
390
278
    if (raw == NULL)
391
0
        goto error;
392
278
    result = raw;
393
394
278
    Py_DECREF(path_or_fd);
395
278
    path_or_fd = NULL;
396
397
278
    modeobj = PyUnicode_FromString(mode);
398
278
    if (modeobj == NULL)
399
0
        goto error;
400
401
    /* buffering */
402
278
    if (buffering < 0) {
403
278
        PyObject *res = _PyObject_CallMethodId(raw, &PyId_isatty, NULL);
404
278
        if (res == NULL)
405
0
            goto error;
406
278
        isatty = PyLong_AsLong(res);
407
278
        Py_DECREF(res);
408
278
        if (isatty == -1 && PyErr_Occurred())
409
0
            goto error;
410
278
    }
411
412
278
    if (buffering == 1 || isatty) {
413
0
        buffering = -1;
414
0
        line_buffering = 1;
415
0
    }
416
278
    else
417
278
        line_buffering = 0;
418
419
278
    if (buffering < 0) {
420
278
        PyObject *blksize_obj;
421
278
        blksize_obj = _PyObject_GetAttrId(raw, &PyId__blksize);
422
278
        if (blksize_obj == NULL)
423
0
            goto error;
424
278
        buffering = PyLong_AsLong(blksize_obj);
425
278
        Py_DECREF(blksize_obj);
426
278
        if (buffering == -1 && PyErr_Occurred())
427
0
            goto error;
428
278
    }
429
278
    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
278
    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
278
    {
449
278
        PyObject *Buffered_class;
450
451
278
        if (updating)
452
0
            Buffered_class = (PyObject *)&PyBufferedRandom_Type;
453
278
        else if (creating || writing || appending)
454
28
            Buffered_class = (PyObject *)&PyBufferedWriter_Type;
455
250
        else if (reading)
456
250
            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
278
        buffer = PyObject_CallFunction(Buffered_class, "Oi", raw, buffering);
464
278
    }
465
278
    if (buffer == NULL)
466
0
        goto error;
467
278
    result = buffer;
468
278
    Py_DECREF(raw);
469
470
471
    /* if binary, returns the buffered file */
472
278
    if (binary) {
473
278
        Py_DECREF(modeobj);
474
278
        return result;
475
278
    }
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
235
{
523
235
    return PyFile_OpenCodeObject(path);
524
235
}
525

526
/*
527
 * Private helpers for the io module.
528
 */
529
530
Py_off_t
531
PyNumber_AsOff_t(PyObject *item, PyObject *err)
532
307
{
533
307
    Py_off_t result;
534
307
    PyObject *runerr;
535
307
    PyObject *value = PyNumber_Index(item);
536
307
    if (value == NULL)
537
0
        return -1;
538
539
    /* We're done if PyLong_AsSsize_t() returns without error. */
540
307
    result = PyLong_AsOff_t(value);
541
307
    if (result != -1 || !(runerr = PyErr_Occurred()))
542
307
        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
307
 finish:
570
307
    Py_DECREF(value);
571
307
    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
30
iomodule_traverse(PyObject *mod, visitproc visit, void *arg) {
616
30
    _PyIO_State *state = IO_MOD_STATE(mod);
617
30
    if (!state->initialized)
618
28
        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
14
{
671
14
    PyObject *m = PyModule_Create(&_PyIO_Module);
672
14
    _PyIO_State *state = NULL;
673
14
    if (m == NULL)
674
0
        return NULL;
675
14
    state = IO_MOD_STATE(m);
676
14
    state->initialized = 0;
677
678
14
#define ADD_TYPE(type, name) \
679
182
    if (PyType_Ready(type) < 0) \
680
182
        goto fail; \
681
182
    Py_INCREF(type); \
682
182
    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
14
    if (PyModule_AddIntMacro(m, DEFAULT_BUFFER_SIZE) < 0)
689
0
        goto fail;
690
691
    /* UnsupportedOperation inherits from ValueError and OSError */
692
14
    state->unsupported_operation = PyObject_CallFunction(
693
14
        (PyObject *)&PyType_Type, "s(OO){}",
694
14
        "UnsupportedOperation", PyExc_OSError, PyExc_ValueError);
695
14
    if (state->unsupported_operation == NULL)
696
0
        goto fail;
697
14
    Py_INCREF(state->unsupported_operation);
698
14
    if (PyModule_AddObject(m, "UnsupportedOperation",
699
14
                           state->unsupported_operation) < 0)
700
0
        goto fail;
701
702
    /* BlockingIOError, for compatibility */
703
14
    Py_INCREF(PyExc_BlockingIOError);
704
14
    if (PyModule_AddObject(m, "BlockingIOError",
705
14
                           (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
28
    ADD_TYPE(&PyIOBase_Type, "_IOBase");
712
14
    ADD_TYPE(&PyRawIOBase_Type, "_RawIOBase");
713
14
    ADD_TYPE(&PyBufferedIOBase_Type, "_BufferedIOBase");
714
14
    ADD_TYPE(&PyTextIOBase_Type, "_TextIOBase");
715
716
    /* Implementation of concrete IO objects. */
717
    /* FileIO */
718
14
    PyFileIO_Type.tp_base = &PyRawIOBase_Type;
719
14
    ADD_TYPE(&PyFileIO_Type, "FileIO");
720
721
    /* BytesIO */
722
14
    PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type;
723
14
    ADD_TYPE(&PyBytesIO_Type, "BytesIO");
724
14
    if (PyType_Ready(&_PyBytesIOBuffer_Type) < 0)
725
0
        goto fail;
726
727
    /* StringIO */
728
14
    PyStringIO_Type.tp_base = &PyTextIOBase_Type;
729
14
    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
14
    PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type;
739
14
    ADD_TYPE(&PyBufferedReader_Type, "BufferedReader");
740
741
    /* BufferedWriter */
742
14
    PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type;
743
14
    ADD_TYPE(&PyBufferedWriter_Type, "BufferedWriter");
744
745
    /* BufferedRWPair */
746
14
    PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type;
747
14
    ADD_TYPE(&PyBufferedRWPair_Type, "BufferedRWPair");
748
749
    /* BufferedRandom */
750
14
    PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type;
751
14
    ADD_TYPE(&PyBufferedRandom_Type, "BufferedRandom");
752
753
    /* TextIOWrapper */
754
14
    PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type;
755
14
    ADD_TYPE(&PyTextIOWrapper_Type, "TextIOWrapper");
756
757
    /* IncrementalNewlineDecoder */
758
14
    ADD_TYPE(&PyIncrementalNewlineDecoder_Type, "IncrementalNewlineDecoder");
759
760
    /* Interned strings */
761
14
#define ADD_INTERNED(name) \
762
336
    if (!_PyIO_str_ ## name && \
763
336
        !(_PyIO_str_ ## name = PyUnicode_InternFromString(# name))) \
764
336
        goto fail;
765
766
14
    ADD_INTERNED(close)
767
14
    ADD_INTERNED(closed)
768
14
    ADD_INTERNED(decode)
769
14
    ADD_INTERNED(encode)
770
14
    ADD_INTERNED(fileno)
771
14
    ADD_INTERNED(flush)
772
14
    ADD_INTERNED(getstate)
773
14
    ADD_INTERNED(isatty)
774
14
    ADD_INTERNED(newlines)
775
14
    ADD_INTERNED(peek)
776
14
    ADD_INTERNED(read)
777
14
    ADD_INTERNED(read1)
778
14
    ADD_INTERNED(readable)
779
14
    ADD_INTERNED(readall)
780
14
    ADD_INTERNED(readinto)
781
14
    ADD_INTERNED(readline)
782
14
    ADD_INTERNED(reset)
783
14
    ADD_INTERNED(seek)
784
14
    ADD_INTERNED(seekable)
785
14
    ADD_INTERNED(setstate)
786
14
    ADD_INTERNED(tell)
787
14
    ADD_INTERNED(truncate)
788
14
    ADD_INTERNED(write)
789
14
    ADD_INTERNED(writable)
790
791
14
    if (!_PyIO_str_nl &&
792
14
        !(_PyIO_str_nl = PyUnicode_InternFromString("\n")))
793
0
        goto fail;
794
795
14
    if (!_PyIO_empty_str &&
796
14
        !(_PyIO_empty_str = PyUnicode_FromStringAndSize(NULL, 0)))
797
0
        goto fail;
798
14
    if (!_PyIO_empty_bytes &&
799
14
        !(_PyIO_empty_bytes = PyBytes_FromStringAndSize(NULL, 0)))
800
0
        goto fail;
801
802
14
    state->initialized = 1;
803
804
14
    return m;
805
806
0
  fail:
807
0
    Py_XDECREF(state->unsupported_operation);
808
0
    Py_DECREF(m);
809
0
    return NULL;
810
14
}