Coverage Report

Created: 2026-10-31 06:21

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
49.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
8.48M
{
83
8.48M
    return PyObject_HasAttrWithError(self, &_Py_ID(__IOBase_closed));
84
8.48M
}
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.45M
{
137
1.45M
    return _PyObject_CallMethod(self, &_Py_ID(seek), "ii", 0, 1);
138
1.45M
}
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.52M
{
175
    /* XXX Should this return the number of bytes written??? */
176
1.52M
    int closed = iobase_is_closed(self);
177
178
1.52M
    if (!closed) {
179
1.52M
        Py_RETURN_NONE;
180
1.52M
    }
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.52M
}
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
6.89M
{
198
6.89M
    return iobase_is_closed(self);
199
6.89M
}
200
201
static int
202
iobase_check_closed(PyObject *self)
203
93.1k
{
204
93.1k
    PyObject *res;
205
93.1k
    int closed;
206
    /* This gets the derived attribute, which is *not* __IOBase_closed
207
       in most cases! */
208
93.1k
    closed = PyObject_GetOptionalAttr(self, &_Py_ID(closed), &res);
209
93.1k
    if (closed > 0) {
210
93.1k
        closed = PyObject_IsTrue(res);
211
93.1k
        Py_DECREF(res);
212
93.1k
        if (closed > 0) {
213
0
            PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
214
0
            return -1;
215
0
        }
216
93.1k
    }
217
93.1k
    return closed;
218
93.1k
}
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
62.6k
{
303
62.6k
    int rc1, rc2, closed = iobase_is_closed(self);
304
305
62.6k
    if (closed < 0) {
306
0
        return NULL;
307
0
    }
308
62.6k
    if (closed) {
309
0
        Py_RETURN_NONE;
310
0
    }
311
312
62.6k
    rc1 = _PyFile_Flush(self);
313
62.6k
    PyObject *exc = PyErr_GetRaisedException();
314
62.6k
    rc2 = PyObject_SetAttr(self, &_Py_ID(__IOBase_closed), Py_True);
315
62.6k
    _PyErr_ChainExceptions1(exc);
316
62.6k
    if (rc1 < 0 || rc2 < 0) {
317
0
        return NULL;
318
0
    }
319
320
62.6k
    Py_RETURN_NONE;
321
62.6k
}
322
323
/* Finalization and garbage collection support */
324
325
static void
326
iobase_finalize(PyObject *self)
327
94.9k
{
328
94.9k
    PyObject *res;
329
94.9k
    int closed;
330
331
    /* Save the current exception, if any. */
332
94.9k
    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
94.9k
    if (PyObject_GetOptionalAttr(self, &_Py_ID(closed), &res) <= 0) {
337
0
        PyErr_Clear();
338
0
        closed = -1;
339
0
    }
340
94.9k
    else {
341
94.9k
        closed = PyObject_IsTrue(res);
342
94.9k
        Py_DECREF(res);
343
94.9k
        if (closed == -1)
344
0
            PyErr_Clear();
345
94.9k
    }
346
94.9k
    if (closed == 0) {
347
        /* Signal close() that it was called as part of the object
348
           finalization process. */
349
9.95k
        if (PyObject_SetAttr(self, &_Py_ID(_finalizing), Py_True))
350
0
            PyErr_Clear();
351
9.95k
        res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(close));
352
9.95k
        if (res == NULL) {
353
0
            PyErr_FormatUnraisable("Exception ignored "
354
0
                                   "while finalizing file %R", self);
355
0
        }
356
9.95k
        else {
357
9.95k
            Py_DECREF(res);
358
9.95k
        }
359
9.95k
    }
360
361
    /* Restore the saved exception. */
362
94.9k
    PyErr_SetRaisedException(exc);
363
94.9k
}
364
365
int
366
_PyIOBase_finalize(PyObject *self)
367
94.9k
{
368
94.9k
    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
94.9k
    is_zombie = (Py_REFCNT(self) == 0);
373
94.9k
    if (is_zombie)
374
94.9k
        return PyObject_CallFinalizerFromDealloc(self);
375
0
    else {
376
0
        PyObject_CallFinalizer(self);
377
0
        return 0;
378
0
    }
379
94.9k
}
380
381
static int
382
iobase_traverse(PyObject *op, visitproc visit, void *arg)
383
5.32k
{
384
5.32k
    iobase *self = iobase_CAST(op);
385
5.32k
    Py_VISIT(Py_TYPE(self));
386
5.32k
    Py_VISIT(self->dict);
387
5.32k
    return 0;
388
5.32k
}
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
44.3k
{
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
44.3k
    iobase *self = iobase_CAST(op);
409
44.3k
    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
44.3k
    PyTypeObject *tp = Py_TYPE(self);
418
44.3k
    _PyObject_GC_UNTRACK(self);
419
44.3k
    FT_CLEAR_WEAKREFS(op, self->weakreflist);
420
44.3k
    Py_CLEAR(self->dict);
421
44.3k
    tp->tp_free(self);
422
44.3k
    Py_DECREF(tp);
423
44.3k
}
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.45M
{
446
1.45M
    PyObject *res  = PyObject_CallMethodNoArgs(self, &_Py_ID(seekable));
447
1.45M
    if (res == NULL)
448
0
        return NULL;
449
1.45M
    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.45M
    if (args == Py_True) {
455
1.45M
        Py_DECREF(res);
456
1.45M
    }
457
1.45M
    return res;
458
1.45M
}
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.2k
{
479
10.2k
    PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(readable));
480
10.2k
    if (res == NULL)
481
0
        return NULL;
482
10.2k
    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.2k
    if (args == Py_True) {
488
10.2k
        Py_DECREF(res);
489
10.2k
    }
490
10.2k
    return res;
491
10.2k
}
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
17.4k
{
512
17.4k
    PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(writable));
513
17.4k
    if (res == NULL)
514
0
        return NULL;
515
17.4k
    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
17.4k
    if (args == Py_True) {
521
17.4k
        Py_DECREF(res);
522
17.4k
    }
523
17.4k
    return res;
524
17.4k
}
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
47.9k
{
538
47.9k
    if (iobase_check_closed(self))
539
0
        return NULL;
540
541
47.9k
    return Py_NewRef(self);
542
47.9k
}
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
47.9k
{
555
47.9k
    return PyObject_CallMethodNoArgs(self, &_Py_ID(close));
556
47.9k
}
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
                    Py_ssize_t remaining = limit - PyBytesWriter_GetSize(writer);
657
0
                    do {
658
0
                        if (n >= PyBytes_GET_SIZE(readahead) || n >= remaining)
659
0
                            break;
660
0
                        if (buf[n++] == '\n')
661
0
                            break;
662
0
                    } while (1);
663
0
                }
664
0
                else {
665
0
                    do {
666
0
                        if (n >= PyBytes_GET_SIZE(readahead))
667
0
                            break;
668
0
                        if (buf[n++] == '\n')
669
0
                            break;
670
0
                    } while (1);
671
0
                }
672
0
                nreadahead = n;
673
0
            }
674
0
            Py_DECREF(readahead);
675
0
        }
676
677
0
        b = _PyObject_CallMethod(self, &_Py_ID(read), "n", nreadahead);
678
0
        if (b == NULL) {
679
            /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
680
               when EINTR occurs so we needn't do it ourselves. */
681
0
            if (_PyIO_trap_eintr()) {
682
0
                continue;
683
0
            }
684
0
            goto fail;
685
0
        }
686
0
        if (!PyBytes_Check(b)) {
687
0
            PyErr_Format(PyExc_OSError,
688
0
                         "read() should have returned a bytes object, "
689
0
                         "not '%.200s'", Py_TYPE(b)->tp_name);
690
0
            Py_DECREF(b);
691
0
            goto fail;
692
0
        }
693
0
        if (PyBytes_GET_SIZE(b) == 0) {
694
0
            Py_DECREF(b);
695
0
            break;
696
0
        }
697
698
0
        if (PyBytesWriter_WriteBytes(writer,
699
0
                                     PyBytes_AS_STRING(b),
700
0
                                     PyBytes_GET_SIZE(b)) < 0) {
701
0
            Py_DECREF(b);
702
0
            goto fail;
703
0
        }
704
705
0
        Py_DECREF(b);
706
707
0
        char *data = PyBytesWriter_GetData(writer);
708
0
        if (data[PyBytesWriter_GetSize(writer) - 1] == '\n')
709
0
            break;
710
0
    }
711
712
0
    Py_XDECREF(peek);
713
0
    return PyBytesWriter_Finish(writer);
714
0
  fail:
715
0
    Py_XDECREF(peek);
716
0
    PyBytesWriter_Discard(writer);
717
0
    return NULL;
718
0
}
719
720
static PyObject *
721
iobase_iter(PyObject *self)
722
45.2k
{
723
45.2k
    if (iobase_check_closed(self))
724
0
        return NULL;
725
726
45.2k
    return Py_NewRef(self);
727
45.2k
}
728
729
static PyObject *
730
iobase_iternext(PyObject *self)
731
0
{
732
0
    PyObject *line = PyObject_CallMethodNoArgs(self, &_Py_ID(readline));
733
734
0
    if (line == NULL)
735
0
        return NULL;
736
737
0
    if (PyObject_Size(line) <= 0) {
738
        /* Error or empty */
739
0
        Py_DECREF(line);
740
0
        return NULL;
741
0
    }
742
743
0
    return line;
744
0
}
745
746
/*[clinic input]
747
_io._IOBase.readlines
748
    hint: Py_ssize_t(accept={int, NoneType}) = -1
749
    /
750
751
Return a list of lines from the stream.
752
753
hint can be specified to control the number of lines read: no more
754
lines will be read if the total size (in bytes/characters) of all
755
lines so far exceeds hint.
756
[clinic start generated code]*/
757
758
static PyObject *
759
_io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint)
760
/*[clinic end generated code: output=2f50421677fa3dea input=9400c786ea9dc416]*/
761
39.3k
{
762
39.3k
    Py_ssize_t length = 0;
763
39.3k
    PyObject *result, *it = NULL;
764
765
39.3k
    result = PyList_New(0);
766
39.3k
    if (result == NULL)
767
0
        return NULL;
768
769
39.3k
    if (hint <= 0) {
770
        /* XXX special-casing this made sense in the Python version in order
771
           to remove the bytecode interpretation overhead, but it could
772
           probably be removed here. */
773
39.3k
        PyObject *ret = PyObject_CallMethodObjArgs(result, &_Py_ID(extend),
774
39.3k
                                                   self, NULL);
775
39.3k
        if (ret == NULL) {
776
0
            goto error;
777
0
        }
778
39.3k
        Py_DECREF(ret);
779
39.3k
        return result;
780
39.3k
    }
781
782
0
    it = PyObject_GetIter(self);
783
0
    if (it == NULL) {
784
0
        goto error;
785
0
    }
786
787
0
    while (1) {
788
0
        Py_ssize_t line_length;
789
0
        PyObject *line = PyIter_Next(it);
790
0
        if (line == NULL) {
791
0
            if (PyErr_Occurred()) {
792
0
                goto error;
793
0
            }
794
0
            else
795
0
                break; /* StopIteration raised */
796
0
        }
797
798
0
        if (PyList_Append(result, line) < 0) {
799
0
            Py_DECREF(line);
800
0
            goto error;
801
0
        }
802
0
        line_length = PyObject_Size(line);
803
0
        Py_DECREF(line);
804
0
        if (line_length < 0) {
805
0
            goto error;
806
0
        }
807
0
        if (line_length > hint - length)
808
0
            break;
809
0
        length += line_length;
810
0
    }
811
812
0
    Py_DECREF(it);
813
0
    return result;
814
815
0
 error:
816
0
    Py_XDECREF(it);
817
0
    Py_DECREF(result);
818
0
    return NULL;
819
0
}
820
821
/*[clinic input]
822
_io._IOBase.writelines
823
    lines: object
824
    /
825
826
Write a list of lines to stream.
827
828
Line separators are not added, so it is usual for each of the
829
lines provided to have a line separator at the end.
830
[clinic start generated code]*/
831
832
static PyObject *
833
_io__IOBase_writelines(PyObject *self, PyObject *lines)
834
/*[clinic end generated code: output=976eb0a9b60a6628 input=cac3fc8864183359]*/
835
0
{
836
0
    PyObject *iter, *res;
837
838
0
    if (iobase_check_closed(self))
839
0
        return NULL;
840
841
0
    iter = PyObject_GetIter(lines);
842
0
    if (iter == NULL)
843
0
        return NULL;
844
845
0
    while (1) {
846
0
        PyObject *line = PyIter_Next(iter);
847
0
        if (line == NULL) {
848
0
            if (PyErr_Occurred()) {
849
0
                Py_DECREF(iter);
850
0
                return NULL;
851
0
            }
852
0
            else
853
0
                break; /* Stop Iteration */
854
0
        }
855
856
0
        res = NULL;
857
0
        do {
858
0
            res = PyObject_CallMethodObjArgs(self, &_Py_ID(write), line, NULL);
859
0
        } while (res == NULL && _PyIO_trap_eintr());
860
0
        Py_DECREF(line);
861
0
        if (res == NULL) {
862
0
            Py_DECREF(iter);
863
0
            return NULL;
864
0
        }
865
0
        Py_DECREF(res);
866
0
    }
867
0
    Py_DECREF(iter);
868
0
    Py_RETURN_NONE;
869
0
}
870
871
#define clinic_state() (find_io_state_by_def(Py_TYPE(self)))
872
#include "clinic/iobase.c.h"
873
#undef clinic_state
874
875
static PyMethodDef iobase_methods[] = {
876
    _IO__IOBASE_SEEK_METHODDEF
877
    _IO__IOBASE_TELL_METHODDEF
878
    _IO__IOBASE_TRUNCATE_METHODDEF
879
    _IO__IOBASE_FLUSH_METHODDEF
880
    _IO__IOBASE_CLOSE_METHODDEF
881
882
    _IO__IOBASE_SEEKABLE_METHODDEF
883
    _IO__IOBASE_READABLE_METHODDEF
884
    _IO__IOBASE_WRITABLE_METHODDEF
885
886
    _IO__IOBASE__CHECKCLOSED_METHODDEF
887
    _IO__IOBASE__CHECKSEEKABLE_METHODDEF
888
    _IO__IOBASE__CHECKREADABLE_METHODDEF
889
    _IO__IOBASE__CHECKWRITABLE_METHODDEF
890
891
    _IO__IOBASE_FILENO_METHODDEF
892
    _IO__IOBASE_ISATTY_METHODDEF
893
894
    _IO__IOBASE___ENTER___METHODDEF
895
    _IO__IOBASE___EXIT___METHODDEF
896
897
    _IO__IOBASE_READLINE_METHODDEF
898
    _IO__IOBASE_READLINES_METHODDEF
899
    _IO__IOBASE_WRITELINES_METHODDEF
900
901
    {NULL, NULL}
902
};
903
904
static PyGetSetDef iobase_getset[] = {
905
    {"__dict__", PyObject_GenericGetDict, NULL, NULL},
906
    _IO__IOBASE_CLOSED_GETSETDEF
907
    {NULL}
908
};
909
910
static struct PyMemberDef iobase_members[] = {
911
    {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(iobase, weakreflist), Py_READONLY},
912
    {"__dictoffset__", Py_T_PYSSIZET, offsetof(iobase, dict), Py_READONLY},
913
    {NULL},
914
};
915
916
917
static PyType_Slot iobase_slots[] = {
918
    {Py_tp_dealloc, iobase_dealloc},
919
    {Py_tp_doc, (void *)iobase_doc},
920
    {Py_tp_traverse, iobase_traverse},
921
    {Py_tp_clear, iobase_clear},
922
    {Py_tp_iter, iobase_iter},
923
    {Py_tp_iternext, iobase_iternext},
924
    {Py_tp_methods, iobase_methods},
925
    {Py_tp_members, iobase_members},
926
    {Py_tp_getset, iobase_getset},
927
    {Py_tp_finalize, iobase_finalize},
928
    {0, NULL},
929
};
930
931
PyType_Spec _Py_iobase_spec = {
932
    .name = "_io._IOBase",
933
    .basicsize = sizeof(iobase),
934
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
935
              Py_TPFLAGS_IMMUTABLETYPE),
936
    .slots = iobase_slots,
937
};
938
939
/*
940
 * RawIOBase class, Inherits from IOBase.
941
 */
942
PyDoc_STRVAR(rawiobase_doc,
943
             "Base class for raw binary I/O.");
944
945
/*
946
 * The read() method is implemented by calling readinto(); derived classes
947
 * that want to support read() only need to implement readinto() as a
948
 * primitive operation.  In general, readinto() can be more efficient than
949
 * read().
950
 *
951
 * (It would be tempting to also provide an implementation of readinto() in
952
 * terms of read(), in case the latter is a more suitable primitive operation,
953
 * but that would lead to nasty recursion in case a subclass doesn't implement
954
 * either.)
955
*/
956
957
/*[clinic input]
958
_io._RawIOBase.read
959
    size as n: Py_ssize_t = -1
960
    /
961
[clinic start generated code]*/
962
963
static PyObject *
964
_io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n)
965
/*[clinic end generated code: output=6cdeb731e3c9f13c input=b6d0dcf6417d1374]*/
966
0
{
967
0
    PyObject *b, *res;
968
969
0
    if (n < 0) {
970
0
        return PyObject_CallMethodNoArgs(self, &_Py_ID(readall));
971
0
    }
972
973
0
    b = PyByteArray_FromStringAndSize(NULL, n);
974
0
    if (b == NULL) {
975
0
        return NULL;
976
0
    }
977
978
0
    res = PyObject_CallMethodObjArgs(self, &_Py_ID(readinto), b, NULL);
979
0
    if (res == NULL || res == Py_None) {
980
0
        goto cleanup;
981
0
    }
982
983
0
    Py_ssize_t bytes_filled = PyNumber_AsSsize_t(res, PyExc_ValueError);
984
0
    Py_CLEAR(res);
985
0
    if (bytes_filled == -1 && PyErr_Occurred()) {
986
0
        goto cleanup;
987
0
    }
988
0
    if (bytes_filled < 0 || bytes_filled > n) {
989
0
        PyErr_Format(PyExc_ValueError,
990
0
                     "readinto returned %zd outside buffer size %zd",
991
0
                     bytes_filled, n);
992
0
        goto cleanup;
993
0
    }
994
0
    if (PyByteArray_Resize(b, bytes_filled) < 0) {
995
0
        goto cleanup;
996
0
    }
997
0
    res = PyObject_CallMethodNoArgs(b, &_Py_ID(take_bytes));
998
999
0
cleanup:
1000
0
    Py_DECREF(b);
1001
0
    return res;
1002
0
}
1003
1004
1005
/*[clinic input]
1006
_io._RawIOBase.readall
1007
1008
Read until EOF, using multiple read() call.
1009
[clinic start generated code]*/
1010
1011
static PyObject *
1012
_io__RawIOBase_readall_impl(PyObject *self)
1013
/*[clinic end generated code: output=1987b9ce929425a0 input=688874141213622a]*/
1014
0
{
1015
0
    PyBytesWriter *writer = PyBytesWriter_Create(0);
1016
0
    if (writer == NULL) {
1017
0
        return NULL;
1018
0
    }
1019
1020
0
    while (1) {
1021
0
        PyObject *data = _PyObject_CallMethod(self, &_Py_ID(read),
1022
0
                                              "i", DEFAULT_BUFFER_SIZE);
1023
0
        if (!data) {
1024
            /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
1025
               when EINTR occurs so we needn't do it ourselves. */
1026
0
            if (_PyIO_trap_eintr()) {
1027
0
                continue;
1028
0
            }
1029
0
            PyBytesWriter_Discard(writer);
1030
0
            return NULL;
1031
0
        }
1032
0
        if (data == Py_None) {
1033
0
            if (PyBytesWriter_GetSize(writer) == 0) {
1034
0
                PyBytesWriter_Discard(writer);
1035
0
                return data;
1036
0
            }
1037
0
            Py_DECREF(data);
1038
0
            break;
1039
0
        }
1040
0
        if (!PyBytes_Check(data)) {
1041
0
            Py_DECREF(data);
1042
0
            PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1043
0
            PyBytesWriter_Discard(writer);
1044
0
            return NULL;
1045
0
        }
1046
0
        if (PyBytes_GET_SIZE(data) == 0) {
1047
            /* EOF */
1048
0
            Py_DECREF(data);
1049
0
            break;
1050
0
        }
1051
0
        if (PyBytesWriter_WriteBytes(writer,
1052
0
                                     PyBytes_AS_STRING(data),
1053
0
                                     PyBytes_GET_SIZE(data)) < 0) {
1054
0
            Py_DECREF(data);
1055
0
            PyBytesWriter_Discard(writer);
1056
0
            return NULL;
1057
0
        }
1058
0
        Py_DECREF(data);
1059
0
    }
1060
0
    return PyBytesWriter_Finish(writer);
1061
0
}
1062
1063
/*[clinic input]
1064
_io._RawIOBase.readinto
1065
    buffer: object
1066
    /
1067
[clinic start generated code]*/
1068
1069
static PyObject *
1070
_io__RawIOBase_readinto(PyObject *self, PyObject *buffer)
1071
/*[clinic end generated code: output=081b8cdfaf3a40ff input=99d4bea2acd659c8]*/
1072
0
{
1073
0
    PyErr_SetNone(PyExc_NotImplementedError);
1074
0
    return NULL;
1075
0
}
1076
1077
/*[clinic input]
1078
_io._RawIOBase.write
1079
    buffer: object
1080
    /
1081
[clinic start generated code]*/
1082
1083
static PyObject *
1084
_io__RawIOBase_write(PyObject *self, PyObject *buffer)
1085
/*[clinic end generated code: output=7add3f2c8715c3a8 input=e6a1534adb876fe2]*/
1086
0
{
1087
0
    PyErr_SetNone(PyExc_NotImplementedError);
1088
    return NULL;
1089
0
}
1090
1091
static PyMethodDef rawiobase_methods[] = {
1092
    _IO__RAWIOBASE_READ_METHODDEF
1093
    _IO__RAWIOBASE_READALL_METHODDEF
1094
    _IO__RAWIOBASE_READINTO_METHODDEF
1095
    _IO__RAWIOBASE_WRITE_METHODDEF
1096
    {NULL, NULL}
1097
};
1098
1099
static PyType_Slot rawiobase_slots[] = {
1100
    {Py_tp_doc, (void *)rawiobase_doc},
1101
    {Py_tp_methods, rawiobase_methods},
1102
    {0, NULL},
1103
};
1104
1105
/* Do not set Py_TPFLAGS_HAVE_GC so that tp_traverse and tp_clear are inherited */
1106
PyType_Spec _Py_rawiobase_spec = {
1107
    .name = "_io._RawIOBase",
1108
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1109
              Py_TPFLAGS_IMMUTABLETYPE),
1110
    .slots = rawiobase_slots,
1111
};