Coverage Report

Created: 2025-07-04 06:49

/src/cpython/Modules/_io/iobase.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
    An implementation of the I/O abstract base classes hierarchy
3
    as defined by PEP 3116 - "New I/O"
4
5
    Classes defined here: IOBase, RawIOBase.
6
7
    Written by Amaury Forgeot d'Arc and Antoine Pitrou
8
*/
9
10
11
#include "Python.h"
12
#include "pycore_call.h"          // _PyObject_CallMethod()
13
#include "pycore_fileutils.h"           // _PyFile_Flush
14
#include "pycore_long.h"          // _PyLong_GetOne()
15
#include "pycore_object.h"        // _PyType_HasFeature()
16
#include "pycore_pyerrors.h"      // _PyErr_ChainExceptions1()
17
#include "pycore_weakref.h"       // FT_CLEAR_WEAKREFS()
18
19
#include <stddef.h>               // offsetof()
20
#include "_iomodule.h"
21
22
/*[clinic input]
23
module _io
24
class _io._IOBase "PyObject *" "clinic_state()->PyIOBase_Type"
25
class _io._RawIOBase "PyObject *" "clinic_state()->PyRawIOBase_Type"
26
[clinic start generated code]*/
27
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9006b7802ab8ea85]*/
28
29
/*
30
 * IOBase class, an abstract class
31
 */
32
33
typedef struct {
34
    PyObject_HEAD
35
36
    PyObject *dict;
37
    PyObject *weakreflist;
38
} iobase;
39
40
12.6k
#define iobase_CAST(op) ((iobase *)(op))
41
42
PyDoc_STRVAR(iobase_doc,
43
    "The abstract base class for all I/O classes.\n"
44
    "\n"
45
    "This class provides dummy implementations for many methods that\n"
46
    "derived classes can override selectively; the default implementations\n"
47
    "represent a file that cannot be read, written or seeked.\n"
48
    "\n"
49
    "Even though IOBase does not declare read, readinto, or write because\n"
50
    "their signatures will vary, implementations and clients should\n"
51
    "consider those methods part of the interface. Also, implementations\n"
52
    "may raise UnsupportedOperation when operations they do not support are\n"
53
    "called.\n"
54
    "\n"
55
    "The basic type used for binary data read from or written to a file is\n"
56
    "bytes. Other bytes-like objects are accepted as method arguments too.\n"
57
    "In some cases (such as readinto), a writable object is required. Text\n"
58
    "I/O classes work with str data.\n"
59
    "\n"
60
    "Note that calling any method (except additional calls to close(),\n"
61
    "which are ignored) on a closed stream should raise a ValueError.\n"
62
    "\n"
63
    "IOBase (and its subclasses) support the iterator protocol, meaning\n"
64
    "that an IOBase object can be iterated over yielding the lines in a\n"
65
    "stream.\n"
66
    "\n"
67
    "IOBase also supports the :keyword:`with` statement. In this example,\n"
68
    "fp is closed after the suite of the with statement is complete:\n"
69
    "\n"
70
    "with open('spam.txt', 'r') as fp:\n"
71
    "    fp.write('Spam and eggs!')\n");
72
73
74
/* Internal methods */
75
76
/* Use this function whenever you want to check the internal `closed` status
77
   of the IOBase object rather than the virtual `closed` attribute as returned
78
   by whatever subclass. */
79
80
static int
81
iobase_is_closed(PyObject *self)
82
32.9k
{
83
32.9k
    return PyObject_HasAttrWithError(self, &_Py_ID(__IOBase_closed));
84
32.9k
}
85
86
static PyObject *
87
iobase_unsupported(_PyIO_State *state, const char *message)
88
0
{
89
0
    PyErr_SetString(state->unsupported_operation, message);
90
0
    return NULL;
91
0
}
92
93
/* Positioning */
94
95
/*[clinic input]
96
_io._IOBase.seek
97
    cls: defining_class
98
    offset: int(unused=True)
99
      The stream position, relative to 'whence'.
100
    whence: int(unused=True, c_default='0') = os.SEEK_SET
101
      The relative position to seek from.
102
    /
103
104
Change the stream position to the given byte offset.
105
106
The offset is interpreted relative to the position indicated by whence.
107
Values for whence are:
108
109
* os.SEEK_SET or 0 -- start of stream (the default); offset should be zero or positive
110
* os.SEEK_CUR or 1 -- current stream position; offset may be negative
111
* os.SEEK_END or 2 -- end of stream; offset is usually negative
112
113
Return the new absolute position.
114
[clinic start generated code]*/
115
116
static PyObject *
117
_io__IOBase_seek_impl(PyObject *self, PyTypeObject *cls,
118
                      int Py_UNUSED(offset), int Py_UNUSED(whence))
119
/*[clinic end generated code: output=8bd74ea6538ded53 input=74211232b363363e]*/
120
0
{
121
0
    _PyIO_State *state = get_io_state_by_cls(cls);
122
0
    return iobase_unsupported(state, "seek");
123
0
}
124
125
/*[clinic input]
126
_io._IOBase.tell
127
128
Return current stream position.
129
[clinic start generated code]*/
130
131
static PyObject *
132
_io__IOBase_tell_impl(PyObject *self)
133
/*[clinic end generated code: output=89a1c0807935abe2 input=04e615fec128801f]*/
134
0
{
135
0
    return _PyObject_CallMethod(self, &_Py_ID(seek), "ii", 0, 1);
136
0
}
137
138
/*[clinic input]
139
_io._IOBase.truncate
140
    cls: defining_class
141
    size: object(unused=True) = None
142
    /
143
144
Truncate file to size bytes.
145
146
File pointer is left unchanged. Size defaults to the current IO position
147
as reported by tell(). Return the new size.
148
[clinic start generated code]*/
149
150
static PyObject *
151
_io__IOBase_truncate_impl(PyObject *self, PyTypeObject *cls,
152
                          PyObject *Py_UNUSED(size))
153
/*[clinic end generated code: output=2013179bff1fe8ef input=660ac20936612c27]*/
154
0
{
155
0
    _PyIO_State *state = get_io_state_by_cls(cls);
156
0
    return iobase_unsupported(state, "truncate");
157
0
}
158
159
/* Flush and close methods */
160
161
/*[clinic input]
162
_io._IOBase.flush
163
164
Flush write buffers, if applicable.
165
166
This is not implemented for read-only and non-blocking streams.
167
[clinic start generated code]*/
168
169
static PyObject *
170
_io__IOBase_flush_impl(PyObject *self)
171
/*[clinic end generated code: output=7cef4b4d54656a3b input=773be121abe270aa]*/
172
12.0k
{
173
    /* XXX Should this return the number of bytes written??? */
174
12.0k
    int closed = iobase_is_closed(self);
175
176
12.0k
    if (!closed) {
177
12.0k
        Py_RETURN_NONE;
178
12.0k
    }
179
0
    if (closed > 0) {
180
0
        PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
181
0
    }
182
0
    return NULL;
183
12.0k
}
184
185
static PyObject *
186
iobase_closed_get(PyObject *self, void *context)
187
9.90k
{
188
9.90k
    int closed = iobase_is_closed(self);
189
9.90k
    if (closed < 0) {
190
0
        return NULL;
191
0
    }
192
9.90k
    return PyBool_FromLong(closed);
193
9.90k
}
194
195
static int
196
iobase_check_closed(PyObject *self)
197
40.8k
{
198
40.8k
    PyObject *res;
199
40.8k
    int closed;
200
    /* This gets the derived attribute, which is *not* __IOBase_closed
201
       in most cases! */
202
40.8k
    closed = PyObject_GetOptionalAttr(self, &_Py_ID(closed), &res);
203
40.8k
    if (closed > 0) {
204
40.8k
        closed = PyObject_IsTrue(res);
205
40.8k
        Py_DECREF(res);
206
40.8k
        if (closed > 0) {
207
0
            PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
208
0
            return -1;
209
0
        }
210
40.8k
    }
211
40.8k
    return closed;
212
40.8k
}
213
214
PyObject *
215
_PyIOBase_check_closed(PyObject *self, PyObject *args)
216
0
{
217
0
    if (iobase_check_closed(self)) {
218
0
        return NULL;
219
0
    }
220
0
    if (args == Py_True) {
221
0
        return Py_None;
222
0
    }
223
0
    Py_RETURN_NONE;
224
0
}
225
226
static PyObject *
227
iobase_check_seekable(PyObject *self, PyObject *args)
228
0
{
229
0
    _PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
230
0
    return _PyIOBase_check_seekable(state, self, args);
231
0
}
232
233
static PyObject *
234
iobase_check_readable(PyObject *self, PyObject *args)
235
0
{
236
0
    _PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
237
0
    return _PyIOBase_check_readable(state, self, args);
238
0
}
239
240
static PyObject *
241
iobase_check_writable(PyObject *self, PyObject *args)
242
0
{
243
0
    _PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
244
0
    return _PyIOBase_check_writable(state, self, args);
245
0
}
246
247
PyObject *
248
_PyIOBase_cannot_pickle(PyObject *self, PyObject *args)
249
0
{
250
0
    PyErr_Format(PyExc_TypeError,
251
0
        "cannot pickle '%.100s' instances", _PyType_Name(Py_TYPE(self)));
252
0
    return NULL;
253
0
}
254
255
/* XXX: IOBase thinks it has to maintain its own internal state in
256
   `__IOBase_closed` and call flush() by itself, but it is redundant with
257
   whatever behaviour a non-trivial derived class will implement. */
258
259
/*[clinic input]
260
_io._IOBase.close
261
262
Flush and close the IO object.
263
264
This method has no effect if the file is already closed.
265
[clinic start generated code]*/
266
267
static PyObject *
268
_io__IOBase_close_impl(PyObject *self)
269
/*[clinic end generated code: output=63c6a6f57d783d6d input=f4494d5c31dbc6b7]*/
270
11.0k
{
271
11.0k
    int rc1, rc2, closed = iobase_is_closed(self);
272
273
11.0k
    if (closed < 0) {
274
0
        return NULL;
275
0
    }
276
11.0k
    if (closed) {
277
0
        Py_RETURN_NONE;
278
0
    }
279
280
11.0k
    rc1 = _PyFile_Flush(self);
281
11.0k
    PyObject *exc = PyErr_GetRaisedException();
282
11.0k
    rc2 = PyObject_SetAttr(self, &_Py_ID(__IOBase_closed), Py_True);
283
11.0k
    _PyErr_ChainExceptions1(exc);
284
11.0k
    if (rc1 < 0 || rc2 < 0) {
285
0
        return NULL;
286
0
    }
287
288
11.0k
    Py_RETURN_NONE;
289
11.0k
}
290
291
/* Finalization and garbage collection support */
292
293
static void
294
iobase_finalize(PyObject *self)
295
12.0k
{
296
12.0k
    PyObject *res;
297
12.0k
    int closed;
298
299
    /* Save the current exception, if any. */
300
12.0k
    PyObject *exc = PyErr_GetRaisedException();
301
302
    /* If `closed` doesn't exist or can't be evaluated as bool, then the
303
       object is probably in an unusable state, so ignore. */
304
12.0k
    if (PyObject_GetOptionalAttr(self, &_Py_ID(closed), &res) <= 0) {
305
0
        PyErr_Clear();
306
0
        closed = -1;
307
0
    }
308
12.0k
    else {
309
12.0k
        closed = PyObject_IsTrue(res);
310
12.0k
        Py_DECREF(res);
311
12.0k
        if (closed == -1)
312
0
            PyErr_Clear();
313
12.0k
    }
314
12.0k
    if (closed == 0) {
315
        /* Signal close() that it was called as part of the object
316
           finalization process. */
317
9.90k
        if (PyObject_SetAttr(self, &_Py_ID(_finalizing), Py_True))
318
0
            PyErr_Clear();
319
9.90k
        res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(close));
320
9.90k
        if (res == NULL) {
321
0
            PyErr_FormatUnraisable("Exception ignored "
322
0
                                   "while finalizing file %R", self);
323
0
        }
324
9.90k
        else {
325
9.90k
            Py_DECREF(res);
326
9.90k
        }
327
9.90k
    }
328
329
    /* Restore the saved exception. */
330
12.0k
    PyErr_SetRaisedException(exc);
331
12.0k
}
332
333
int
334
_PyIOBase_finalize(PyObject *self)
335
12.0k
{
336
12.0k
    int is_zombie;
337
338
    /* If _PyIOBase_finalize() is called from a destructor, we need to
339
       resurrect the object as calling close() can invoke arbitrary code. */
340
12.0k
    is_zombie = (Py_REFCNT(self) == 0);
341
12.0k
    if (is_zombie)
342
12.0k
        return PyObject_CallFinalizerFromDealloc(self);
343
0
    else {
344
0
        PyObject_CallFinalizer(self);
345
0
        return 0;
346
0
    }
347
12.0k
}
348
349
static int
350
iobase_traverse(PyObject *op, visitproc visit, void *arg)
351
2.70k
{
352
2.70k
    iobase *self = iobase_CAST(op);
353
2.70k
    Py_VISIT(Py_TYPE(self));
354
2.70k
    Py_VISIT(self->dict);
355
2.70k
    return 0;
356
2.70k
}
357
358
static int
359
iobase_clear(PyObject *op)
360
0
{
361
0
    iobase *self = iobase_CAST(op);
362
0
    Py_CLEAR(self->dict);
363
0
    return 0;
364
0
}
365
366
/* Destructor */
367
368
static void
369
iobase_dealloc(PyObject *op)
370
9.90k
{
371
    /* NOTE: since IOBaseObject has its own dict, Python-defined attributes
372
       are still available here for close() to use.
373
       However, if the derived class declares a __slots__, those slots are
374
       already gone.
375
    */
376
9.90k
    iobase *self = iobase_CAST(op);
377
9.90k
    if (_PyIOBase_finalize(op) < 0) {
378
        /* When called from a heap type's dealloc, the type will be
379
           decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */
380
0
        if (_PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE)) {
381
0
            Py_INCREF(Py_TYPE(self));
382
0
        }
383
0
        return;
384
0
    }
385
9.90k
    PyTypeObject *tp = Py_TYPE(self);
386
9.90k
    _PyObject_GC_UNTRACK(self);
387
9.90k
    FT_CLEAR_WEAKREFS(op, self->weakreflist);
388
9.90k
    Py_CLEAR(self->dict);
389
9.90k
    tp->tp_free(self);
390
9.90k
    Py_DECREF(tp);
391
9.90k
}
392
393
/* Inquiry methods */
394
395
/*[clinic input]
396
_io._IOBase.seekable
397
398
Return whether object supports random access.
399
400
If False, seek(), tell() and truncate() will raise OSError.
401
This method may need to do a test seek().
402
[clinic start generated code]*/
403
404
static PyObject *
405
_io__IOBase_seekable_impl(PyObject *self)
406
/*[clinic end generated code: output=4c24c67f5f32a43d input=b976622f7fdf3063]*/
407
0
{
408
0
    Py_RETURN_FALSE;
409
0
}
410
411
PyObject *
412
_PyIOBase_check_seekable(_PyIO_State *state, PyObject *self, PyObject *args)
413
6
{
414
6
    PyObject *res  = PyObject_CallMethodNoArgs(self, &_Py_ID(seekable));
415
6
    if (res == NULL)
416
0
        return NULL;
417
6
    if (res != Py_True) {
418
0
        Py_CLEAR(res);
419
0
        iobase_unsupported(state, "File or stream is not seekable.");
420
0
        return NULL;
421
0
    }
422
6
    if (args == Py_True) {
423
6
        Py_DECREF(res);
424
6
    }
425
6
    return res;
426
6
}
427
428
/*[clinic input]
429
_io._IOBase.readable
430
431
Return whether object was opened for reading.
432
433
If False, read() will raise OSError.
434
[clinic start generated code]*/
435
436
static PyObject *
437
_io__IOBase_readable_impl(PyObject *self)
438
/*[clinic end generated code: output=e48089250686388b input=285b3b866a0ec35f]*/
439
32
{
440
32
    Py_RETURN_FALSE;
441
32
}
442
443
/* May be called with any object */
444
PyObject *
445
_PyIOBase_check_readable(_PyIO_State *state, PyObject *self, PyObject *args)
446
960
{
447
960
    PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(readable));
448
960
    if (res == NULL)
449
0
        return NULL;
450
960
    if (res != Py_True) {
451
0
        Py_CLEAR(res);
452
0
        iobase_unsupported(state, "File or stream is not readable.");
453
0
        return NULL;
454
0
    }
455
960
    if (args == Py_True) {
456
960
        Py_DECREF(res);
457
960
    }
458
960
    return res;
459
960
}
460
461
/*[clinic input]
462
_io._IOBase.writable
463
464
Return whether object was opened for writing.
465
466
If False, write() will raise OSError.
467
[clinic start generated code]*/
468
469
static PyObject *
470
_io__IOBase_writable_impl(PyObject *self)
471
/*[clinic end generated code: output=406001d0985be14f input=9dcac18a013a05b5]*/
472
16
{
473
16
    Py_RETURN_FALSE;
474
16
}
475
476
/* May be called with any object */
477
PyObject *
478
_PyIOBase_check_writable(_PyIO_State *state, PyObject *self, PyObject *args)
479
32
{
480
32
    PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(writable));
481
32
    if (res == NULL)
482
0
        return NULL;
483
32
    if (res != Py_True) {
484
0
        Py_CLEAR(res);
485
0
        iobase_unsupported(state, "File or stream is not writable.");
486
0
        return NULL;
487
0
    }
488
32
    if (args == Py_True) {
489
32
        Py_DECREF(res);
490
32
    }
491
32
    return res;
492
32
}
493
494
/* Context manager */
495
496
static PyObject *
497
iobase_enter(PyObject *self, PyObject *args)
498
1.16k
{
499
1.16k
    if (iobase_check_closed(self))
500
0
        return NULL;
501
502
1.16k
    return Py_NewRef(self);
503
1.16k
}
504
505
static PyObject *
506
iobase_exit(PyObject *self, PyObject *args)
507
1.16k
{
508
1.16k
    return PyObject_CallMethodNoArgs(self, &_Py_ID(close));
509
1.16k
}
510
511
/* Lower-level APIs */
512
513
/* XXX Should these be present even if unimplemented? */
514
515
/*[clinic input]
516
_io._IOBase.fileno
517
    cls: defining_class
518
    /
519
520
Return underlying file descriptor if one exists.
521
522
Raise OSError if the IO object does not use a file descriptor.
523
[clinic start generated code]*/
524
525
static PyObject *
526
_io__IOBase_fileno_impl(PyObject *self, PyTypeObject *cls)
527
/*[clinic end generated code: output=7caaa32a6f4ada3d input=1927c8bea5c85099]*/
528
0
{
529
0
    _PyIO_State *state = get_io_state_by_cls(cls);
530
0
    return iobase_unsupported(state, "fileno");
531
0
}
532
533
/*[clinic input]
534
_io._IOBase.isatty
535
536
Return whether this is an 'interactive' stream.
537
538
Return False if it can't be determined.
539
[clinic start generated code]*/
540
541
static PyObject *
542
_io__IOBase_isatty_impl(PyObject *self)
543
/*[clinic end generated code: output=60cab77cede41cdd input=9ef76530d368458b]*/
544
0
{
545
0
    if (iobase_check_closed(self))
546
0
        return NULL;
547
0
    Py_RETURN_FALSE;
548
0
}
549
550
/* Readline(s) and writelines */
551
552
/*[clinic input]
553
_io._IOBase.readline
554
    size as limit: Py_ssize_t(accept={int, NoneType}) = -1
555
    /
556
557
Read and return a line from the stream.
558
559
If size is specified, at most size bytes will be read.
560
561
The line terminator is always b'\n' for binary files; for text
562
files, the newlines argument to open can be used to select the line
563
terminator(s) recognized.
564
[clinic start generated code]*/
565
566
static PyObject *
567
_io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit)
568
/*[clinic end generated code: output=4479f79b58187840 input=d0c596794e877bff]*/
569
0
{
570
    /* For backwards compatibility, a (slowish) readline(). */
571
572
0
    PyObject *peek, *buffer, *result;
573
0
    Py_ssize_t old_size = -1;
574
575
0
    if (PyObject_GetOptionalAttr(self, &_Py_ID(peek), &peek) < 0) {
576
0
        return NULL;
577
0
    }
578
579
0
    buffer = PyByteArray_FromStringAndSize(NULL, 0);
580
0
    if (buffer == NULL) {
581
0
        Py_XDECREF(peek);
582
0
        return NULL;
583
0
    }
584
585
0
    while (limit < 0 || PyByteArray_GET_SIZE(buffer) < limit) {
586
0
        Py_ssize_t nreadahead = 1;
587
0
        PyObject *b;
588
589
0
        if (peek != NULL) {
590
0
            PyObject *readahead = PyObject_CallOneArg(peek, _PyLong_GetOne());
591
0
            if (readahead == NULL) {
592
                /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
593
                   when EINTR occurs so we needn't do it ourselves. */
594
0
                if (_PyIO_trap_eintr()) {
595
0
                    continue;
596
0
                }
597
0
                goto fail;
598
0
            }
599
0
            if (!PyBytes_Check(readahead)) {
600
0
                PyErr_Format(PyExc_OSError,
601
0
                             "peek() should have returned a bytes object, "
602
0
                             "not '%.200s'", Py_TYPE(readahead)->tp_name);
603
0
                Py_DECREF(readahead);
604
0
                goto fail;
605
0
            }
606
0
            if (PyBytes_GET_SIZE(readahead) > 0) {
607
0
                Py_ssize_t n = 0;
608
0
                const char *buf = PyBytes_AS_STRING(readahead);
609
0
                if (limit >= 0) {
610
0
                    do {
611
0
                        if (n >= PyBytes_GET_SIZE(readahead) || n >= limit)
612
0
                            break;
613
0
                        if (buf[n++] == '\n')
614
0
                            break;
615
0
                    } while (1);
616
0
                }
617
0
                else {
618
0
                    do {
619
0
                        if (n >= PyBytes_GET_SIZE(readahead))
620
0
                            break;
621
0
                        if (buf[n++] == '\n')
622
0
                            break;
623
0
                    } while (1);
624
0
                }
625
0
                nreadahead = n;
626
0
            }
627
0
            Py_DECREF(readahead);
628
0
        }
629
630
0
        b = _PyObject_CallMethod(self, &_Py_ID(read), "n", nreadahead);
631
0
        if (b == NULL) {
632
            /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
633
               when EINTR occurs so we needn't do it ourselves. */
634
0
            if (_PyIO_trap_eintr()) {
635
0
                continue;
636
0
            }
637
0
            goto fail;
638
0
        }
639
0
        if (!PyBytes_Check(b)) {
640
0
            PyErr_Format(PyExc_OSError,
641
0
                         "read() should have returned a bytes object, "
642
0
                         "not '%.200s'", Py_TYPE(b)->tp_name);
643
0
            Py_DECREF(b);
644
0
            goto fail;
645
0
        }
646
0
        if (PyBytes_GET_SIZE(b) == 0) {
647
0
            Py_DECREF(b);
648
0
            break;
649
0
        }
650
651
0
        old_size = PyByteArray_GET_SIZE(buffer);
652
0
        if (PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b)) < 0) {
653
0
            Py_DECREF(b);
654
0
            goto fail;
655
0
        }
656
0
        memcpy(PyByteArray_AS_STRING(buffer) + old_size,
657
0
               PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b));
658
659
0
        Py_DECREF(b);
660
661
0
        if (PyByteArray_AS_STRING(buffer)[PyByteArray_GET_SIZE(buffer) - 1] == '\n')
662
0
            break;
663
0
    }
664
665
0
    result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(buffer),
666
0
                                       PyByteArray_GET_SIZE(buffer));
667
0
    Py_XDECREF(peek);
668
0
    Py_DECREF(buffer);
669
0
    return result;
670
0
  fail:
671
0
    Py_XDECREF(peek);
672
0
    Py_DECREF(buffer);
673
0
    return NULL;
674
0
}
675
676
static PyObject *
677
iobase_iter(PyObject *self)
678
39.7k
{
679
39.7k
    if (iobase_check_closed(self))
680
0
        return NULL;
681
682
39.7k
    return Py_NewRef(self);
683
39.7k
}
684
685
static PyObject *
686
iobase_iternext(PyObject *self)
687
0
{
688
0
    PyObject *line = PyObject_CallMethodNoArgs(self, &_Py_ID(readline));
689
690
0
    if (line == NULL)
691
0
        return NULL;
692
693
0
    if (PyObject_Size(line) <= 0) {
694
        /* Error or empty */
695
0
        Py_DECREF(line);
696
0
        return NULL;
697
0
    }
698
699
0
    return line;
700
0
}
701
702
/*[clinic input]
703
_io._IOBase.readlines
704
    hint: Py_ssize_t(accept={int, NoneType}) = -1
705
    /
706
707
Return a list of lines from the stream.
708
709
hint can be specified to control the number of lines read: no more
710
lines will be read if the total size (in bytes/characters) of all
711
lines so far exceeds hint.
712
[clinic start generated code]*/
713
714
static PyObject *
715
_io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint)
716
/*[clinic end generated code: output=2f50421677fa3dea input=9400c786ea9dc416]*/
717
39.7k
{
718
39.7k
    Py_ssize_t length = 0;
719
39.7k
    PyObject *result, *it = NULL;
720
721
39.7k
    result = PyList_New(0);
722
39.7k
    if (result == NULL)
723
0
        return NULL;
724
725
39.7k
    if (hint <= 0) {
726
        /* XXX special-casing this made sense in the Python version in order
727
           to remove the bytecode interpretation overhead, but it could
728
           probably be removed here. */
729
39.7k
        PyObject *ret = PyObject_CallMethodObjArgs(result, &_Py_ID(extend),
730
39.7k
                                                   self, NULL);
731
39.7k
        if (ret == NULL) {
732
0
            goto error;
733
0
        }
734
39.7k
        Py_DECREF(ret);
735
39.7k
        return result;
736
39.7k
    }
737
738
0
    it = PyObject_GetIter(self);
739
0
    if (it == NULL) {
740
0
        goto error;
741
0
    }
742
743
0
    while (1) {
744
0
        Py_ssize_t line_length;
745
0
        PyObject *line = PyIter_Next(it);
746
0
        if (line == NULL) {
747
0
            if (PyErr_Occurred()) {
748
0
                goto error;
749
0
            }
750
0
            else
751
0
                break; /* StopIteration raised */
752
0
        }
753
754
0
        if (PyList_Append(result, line) < 0) {
755
0
            Py_DECREF(line);
756
0
            goto error;
757
0
        }
758
0
        line_length = PyObject_Size(line);
759
0
        Py_DECREF(line);
760
0
        if (line_length < 0) {
761
0
            goto error;
762
0
        }
763
0
        if (line_length > hint - length)
764
0
            break;
765
0
        length += line_length;
766
0
    }
767
768
0
    Py_DECREF(it);
769
0
    return result;
770
771
0
 error:
772
0
    Py_XDECREF(it);
773
0
    Py_DECREF(result);
774
0
    return NULL;
775
0
}
776
777
/*[clinic input]
778
_io._IOBase.writelines
779
    lines: object
780
    /
781
782
Write a list of lines to stream.
783
784
Line separators are not added, so it is usual for each of the
785
lines provided to have a line separator at the end.
786
[clinic start generated code]*/
787
788
static PyObject *
789
_io__IOBase_writelines(PyObject *self, PyObject *lines)
790
/*[clinic end generated code: output=976eb0a9b60a6628 input=cac3fc8864183359]*/
791
0
{
792
0
    PyObject *iter, *res;
793
794
0
    if (iobase_check_closed(self))
795
0
        return NULL;
796
797
0
    iter = PyObject_GetIter(lines);
798
0
    if (iter == NULL)
799
0
        return NULL;
800
801
0
    while (1) {
802
0
        PyObject *line = PyIter_Next(iter);
803
0
        if (line == NULL) {
804
0
            if (PyErr_Occurred()) {
805
0
                Py_DECREF(iter);
806
0
                return NULL;
807
0
            }
808
0
            else
809
0
                break; /* Stop Iteration */
810
0
        }
811
812
0
        res = NULL;
813
0
        do {
814
0
            res = PyObject_CallMethodObjArgs(self, &_Py_ID(write), line, NULL);
815
0
        } while (res == NULL && _PyIO_trap_eintr());
816
0
        Py_DECREF(line);
817
0
        if (res == NULL) {
818
0
            Py_DECREF(iter);
819
0
            return NULL;
820
0
        }
821
0
        Py_DECREF(res);
822
0
    }
823
0
    Py_DECREF(iter);
824
0
    Py_RETURN_NONE;
825
0
}
826
827
#define clinic_state() (find_io_state_by_def(Py_TYPE(self)))
828
#include "clinic/iobase.c.h"
829
#undef clinic_state
830
831
static PyMethodDef iobase_methods[] = {
832
    _IO__IOBASE_SEEK_METHODDEF
833
    _IO__IOBASE_TELL_METHODDEF
834
    _IO__IOBASE_TRUNCATE_METHODDEF
835
    _IO__IOBASE_FLUSH_METHODDEF
836
    _IO__IOBASE_CLOSE_METHODDEF
837
838
    _IO__IOBASE_SEEKABLE_METHODDEF
839
    _IO__IOBASE_READABLE_METHODDEF
840
    _IO__IOBASE_WRITABLE_METHODDEF
841
842
    {"_checkClosed",   _PyIOBase_check_closed, METH_NOARGS},
843
    {"_checkSeekable", iobase_check_seekable, METH_NOARGS},
844
    {"_checkReadable", iobase_check_readable, METH_NOARGS},
845
    {"_checkWritable", iobase_check_writable, METH_NOARGS},
846
847
    _IO__IOBASE_FILENO_METHODDEF
848
    _IO__IOBASE_ISATTY_METHODDEF
849
850
    {"__enter__", iobase_enter, METH_NOARGS},
851
    {"__exit__", iobase_exit, METH_VARARGS},
852
853
    _IO__IOBASE_READLINE_METHODDEF
854
    _IO__IOBASE_READLINES_METHODDEF
855
    _IO__IOBASE_WRITELINES_METHODDEF
856
857
    {NULL, NULL}
858
};
859
860
static PyGetSetDef iobase_getset[] = {
861
    {"__dict__", PyObject_GenericGetDict, NULL, NULL},
862
    {"closed", iobase_closed_get, NULL, NULL},
863
    {NULL}
864
};
865
866
static struct PyMemberDef iobase_members[] = {
867
    {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(iobase, weakreflist), Py_READONLY},
868
    {"__dictoffset__", Py_T_PYSSIZET, offsetof(iobase, dict), Py_READONLY},
869
    {NULL},
870
};
871
872
873
static PyType_Slot iobase_slots[] = {
874
    {Py_tp_dealloc, iobase_dealloc},
875
    {Py_tp_doc, (void *)iobase_doc},
876
    {Py_tp_traverse, iobase_traverse},
877
    {Py_tp_clear, iobase_clear},
878
    {Py_tp_iter, iobase_iter},
879
    {Py_tp_iternext, iobase_iternext},
880
    {Py_tp_methods, iobase_methods},
881
    {Py_tp_members, iobase_members},
882
    {Py_tp_getset, iobase_getset},
883
    {Py_tp_finalize, iobase_finalize},
884
    {0, NULL},
885
};
886
887
PyType_Spec iobase_spec = {
888
    .name = "_io._IOBase",
889
    .basicsize = sizeof(iobase),
890
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
891
              Py_TPFLAGS_IMMUTABLETYPE),
892
    .slots = iobase_slots,
893
};
894
895
/*
896
 * RawIOBase class, Inherits from IOBase.
897
 */
898
PyDoc_STRVAR(rawiobase_doc,
899
             "Base class for raw binary I/O.");
900
901
/*
902
 * The read() method is implemented by calling readinto(); derived classes
903
 * that want to support read() only need to implement readinto() as a
904
 * primitive operation.  In general, readinto() can be more efficient than
905
 * read().
906
 *
907
 * (It would be tempting to also provide an implementation of readinto() in
908
 * terms of read(), in case the latter is a more suitable primitive operation,
909
 * but that would lead to nasty recursion in case a subclass doesn't implement
910
 * either.)
911
*/
912
913
/*[clinic input]
914
_io._RawIOBase.read
915
    size as n: Py_ssize_t = -1
916
    /
917
[clinic start generated code]*/
918
919
static PyObject *
920
_io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n)
921
/*[clinic end generated code: output=6cdeb731e3c9f13c input=b6d0dcf6417d1374]*/
922
0
{
923
0
    PyObject *b, *res;
924
925
0
    if (n < 0) {
926
0
        return PyObject_CallMethodNoArgs(self, &_Py_ID(readall));
927
0
    }
928
929
    /* TODO: allocate a bytes object directly instead and manually construct
930
       a writable memoryview pointing to it. */
931
0
    b = PyByteArray_FromStringAndSize(NULL, n);
932
0
    if (b == NULL)
933
0
        return NULL;
934
935
0
    res = PyObject_CallMethodObjArgs(self, &_Py_ID(readinto), b, NULL);
936
0
    if (res == NULL || res == Py_None) {
937
0
        Py_DECREF(b);
938
0
        return res;
939
0
    }
940
941
0
    n = PyNumber_AsSsize_t(res, PyExc_ValueError);
942
0
    Py_DECREF(res);
943
0
    if (n == -1 && PyErr_Occurred()) {
944
0
        Py_DECREF(b);
945
0
        return NULL;
946
0
    }
947
948
0
    res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n);
949
0
    Py_DECREF(b);
950
0
    return res;
951
0
}
952
953
954
/*[clinic input]
955
_io._RawIOBase.readall
956
957
Read until EOF, using multiple read() call.
958
[clinic start generated code]*/
959
960
static PyObject *
961
_io__RawIOBase_readall_impl(PyObject *self)
962
/*[clinic end generated code: output=1987b9ce929425a0 input=688874141213622a]*/
963
0
{
964
0
    int r;
965
0
    PyObject *chunks = PyList_New(0);
966
0
    PyObject *result;
967
968
0
    if (chunks == NULL)
969
0
        return NULL;
970
971
0
    while (1) {
972
0
        PyObject *data = _PyObject_CallMethod(self, &_Py_ID(read),
973
0
                                              "i", DEFAULT_BUFFER_SIZE);
974
0
        if (!data) {
975
            /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
976
               when EINTR occurs so we needn't do it ourselves. */
977
0
            if (_PyIO_trap_eintr()) {
978
0
                continue;
979
0
            }
980
0
            Py_DECREF(chunks);
981
0
            return NULL;
982
0
        }
983
0
        if (data == Py_None) {
984
0
            if (PyList_GET_SIZE(chunks) == 0) {
985
0
                Py_DECREF(chunks);
986
0
                return data;
987
0
            }
988
0
            Py_DECREF(data);
989
0
            break;
990
0
        }
991
0
        if (!PyBytes_Check(data)) {
992
0
            Py_DECREF(chunks);
993
0
            Py_DECREF(data);
994
0
            PyErr_SetString(PyExc_TypeError, "read() should return bytes");
995
0
            return NULL;
996
0
        }
997
0
        if (PyBytes_GET_SIZE(data) == 0) {
998
            /* EOF */
999
0
            Py_DECREF(data);
1000
0
            break;
1001
0
        }
1002
0
        r = PyList_Append(chunks, data);
1003
0
        Py_DECREF(data);
1004
0
        if (r < 0) {
1005
0
            Py_DECREF(chunks);
1006
0
            return NULL;
1007
0
        }
1008
0
    }
1009
0
    result = PyBytes_Join((PyObject *)&_Py_SINGLETON(bytes_empty), chunks);
1010
0
    Py_DECREF(chunks);
1011
0
    return result;
1012
0
}
1013
1014
static PyObject *
1015
rawiobase_readinto(PyObject *self, PyObject *args)
1016
0
{
1017
0
    PyErr_SetNone(PyExc_NotImplementedError);
1018
0
    return NULL;
1019
0
}
1020
1021
static PyObject *
1022
rawiobase_write(PyObject *self, PyObject *args)
1023
0
{
1024
0
    PyErr_SetNone(PyExc_NotImplementedError);
1025
0
    return NULL;
1026
0
}
1027
1028
static PyMethodDef rawiobase_methods[] = {
1029
    _IO__RAWIOBASE_READ_METHODDEF
1030
    _IO__RAWIOBASE_READALL_METHODDEF
1031
    {"readinto", rawiobase_readinto, METH_VARARGS},
1032
    {"write", rawiobase_write, METH_VARARGS},
1033
    {NULL, NULL}
1034
};
1035
1036
static PyType_Slot rawiobase_slots[] = {
1037
    {Py_tp_doc, (void *)rawiobase_doc},
1038
    {Py_tp_methods, rawiobase_methods},
1039
    {0, NULL},
1040
};
1041
1042
/* Do not set Py_TPFLAGS_HAVE_GC so that tp_traverse and tp_clear are inherited */
1043
PyType_Spec rawiobase_spec = {
1044
    .name = "_io._RawIOBase",
1045
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1046
              Py_TPFLAGS_IMMUTABLETYPE),
1047
    .slots = rawiobase_slots,
1048
};