Coverage Report

Created: 2026-05-30 06:18

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