Coverage Report

Created: 2026-10-17 06:15

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