Coverage Report

Created: 2026-09-03 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython3/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
0
#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
846
{
83
846
    return PyObject_HasAttrWithError(self, &_Py_ID(__IOBase_closed));
84
846
}
85
86
static PyObject *
87
iobase_unsupported(_PyIO_State *state, const char *message)
88
0
{
89
0
    PyErr_SetString(state->unsupported_operation, message);
90
0
    return NULL;
91
0
}
92
93
/* Positioning */
94
95
/*[clinic input]
96
_io._IOBase.seek
97
    cls: defining_class
98
    offset: int(unused=True)
99
      The stream position, relative to 'whence'.
100
    whence: int(unused=True, c_default='0') = os.SEEK_SET
101
      The relative position to seek from.
102
    /
103
104
Change the stream position to the given byte offset.
105
106
The offset is interpreted relative to the position indicated by
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
0
{
123
0
    _PyIO_State *state = get_io_state_by_cls(cls);
124
0
    return iobase_unsupported(state, "seek");
125
0
}
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
0
{
137
0
    return _PyObject_CallMethod(self, &_Py_ID(seek), "ii", 0, 1);
138
0
}
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
565
{
175
    /* XXX Should this return the number of bytes written??? */
176
565
    int closed = iobase_is_closed(self);
177
178
565
    if (!closed) {
179
565
        Py_RETURN_NONE;
180
565
    }
181
0
    if (closed > 0) {
182
0
        PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
183
0
    }
184
0
    return NULL;
185
565
}
186
187
static PyObject *
188
iobase_closed_get(PyObject *self, void *context)
189
0
{
190
0
    int closed = iobase_is_closed(self);
191
0
    if (closed < 0) {
192
0
        return NULL;
193
0
    }
194
0
    return PyBool_FromLong(closed);
195
0
}
196
197
static int
198
iobase_check_closed(PyObject *self)
199
284
{
200
284
    PyObject *res;
201
284
    int closed;
202
    /* This gets the derived attribute, which is *not* __IOBase_closed
203
       in most cases! */
204
284
    closed = PyObject_GetOptionalAttr(self, &_Py_ID(closed), &res);
205
284
    if (closed > 0) {
206
284
        closed = PyObject_IsTrue(res);
207
284
        Py_DECREF(res);
208
284
        if (closed > 0) {
209
0
            PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
210
0
            return -1;
211
0
        }
212
284
    }
213
284
    return closed;
214
284
}
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
281
{
273
281
    int rc1, rc2, closed = iobase_is_closed(self);
274
275
281
    if (closed < 0) {
276
0
        return NULL;
277
0
    }
278
281
    if (closed) {
279
0
        Py_RETURN_NONE;
280
0
    }
281
282
281
    rc1 = _PyFile_Flush(self);
283
281
    PyObject *exc = PyErr_GetRaisedException();
284
281
    rc2 = PyObject_SetAttr(self, &_Py_ID(__IOBase_closed), Py_True);
285
281
    _PyErr_ChainExceptions1(exc);
286
281
    if (rc1 < 0 || rc2 < 0) {
287
0
        return NULL;
288
0
    }
289
290
281
    Py_RETURN_NONE;
291
281
}
292
293
/* Finalization and garbage collection support */
294
295
static void
296
iobase_finalize(PyObject *self)
297
565
{
298
565
    PyObject *res;
299
565
    int closed;
300
301
    /* Save the current exception, if any. */
302
565
    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
565
    if (PyObject_GetOptionalAttr(self, &_Py_ID(closed), &res) <= 0) {
307
0
        PyErr_Clear();
308
0
        closed = -1;
309
0
    }
310
565
    else {
311
565
        closed = PyObject_IsTrue(res);
312
565
        Py_DECREF(res);
313
565
        if (closed == -1)
314
0
            PyErr_Clear();
315
565
    }
316
565
    if (closed == 0) {
317
        /* Signal close() that it was called as part of the object
318
           finalization process. */
319
0
        if (PyObject_SetAttr(self, &_Py_ID(_finalizing), Py_True))
320
0
            PyErr_Clear();
321
0
        res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(close));
322
0
        if (res == NULL) {
323
0
            PyErr_FormatUnraisable("Exception ignored "
324
0
                                   "while finalizing file %R", self);
325
0
        }
326
0
        else {
327
0
            Py_DECREF(res);
328
0
        }
329
0
    }
330
331
    /* Restore the saved exception. */
332
565
    PyErr_SetRaisedException(exc);
333
565
}
334
335
int
336
_PyIOBase_finalize(PyObject *self)
337
565
{
338
565
    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
565
    is_zombie = (Py_REFCNT(self) == 0);
343
565
    if (is_zombie)
344
565
        return PyObject_CallFinalizerFromDealloc(self);
345
0
    else {
346
0
        PyObject_CallFinalizer(self);
347
0
        return 0;
348
0
    }
349
565
}
350
351
static int
352
iobase_traverse(PyObject *op, visitproc visit, void *arg)
353
0
{
354
0
    iobase *self = iobase_CAST(op);
355
0
    Py_VISIT(Py_TYPE(self));
356
0
    Py_VISIT(self->dict);
357
0
    return 0;
358
0
}
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
0
{
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
0
    iobase *self = iobase_CAST(op);
379
0
    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
0
    PyTypeObject *tp = Py_TYPE(self);
388
0
    _PyObject_GC_UNTRACK(self);
389
0
    FT_CLEAR_WEAKREFS(op, self->weakreflist);
390
0
    Py_CLEAR(self->dict);
391
0
    tp->tp_free(self);
392
0
    Py_DECREF(tp);
393
0
}
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
3
{
416
3
    PyObject *res  = PyObject_CallMethodNoArgs(self, &_Py_ID(seekable));
417
3
    if (res == NULL)
418
0
        return NULL;
419
3
    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
3
    if (args == Py_True) {
425
3
        Py_DECREF(res);
426
3
    }
427
3
    return res;
428
3
}
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
42
{
442
42
    Py_RETURN_FALSE;
443
42
}
444
445
/* May be called with any object */
446
PyObject *
447
_PyIOBase_check_readable(_PyIO_State *state, PyObject *self, PyObject *args)
448
302
{
449
302
    PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(readable));
450
302
    if (res == NULL)
451
0
        return NULL;
452
302
    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
302
    if (args == Py_True) {
458
302
        Py_DECREF(res);
459
302
    }
460
302
    return res;
461
302
}
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
24
{
475
24
    Py_RETURN_FALSE;
476
24
}
477
478
/* May be called with any object */
479
PyObject *
480
_PyIOBase_check_writable(_PyIO_State *state, PyObject *self, PyObject *args)
481
42
{
482
42
    PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(writable));
483
42
    if (res == NULL)
484
0
        return NULL;
485
42
    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
42
    if (args == Py_True) {
491
42
        Py_DECREF(res);
492
42
    }
493
42
    return res;
494
42
}
495
496
/* Context manager */
497
498
static PyObject *
499
iobase_enter(PyObject *self, PyObject *args)
500
281
{
501
281
    if (iobase_check_closed(self))
502
0
        return NULL;
503
504
281
    return Py_NewRef(self);
505
281
}
506
507
static PyObject *
508
iobase_exit(PyObject *self, PyObject *args)
509
281
{
510
281
    return PyObject_CallMethodNoArgs(self, &_Py_ID(close));
511
281
}
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
3
{
681
3
    if (iobase_check_closed(self))
682
0
        return NULL;
683
684
3
    return Py_NewRef(self);
685
3
}
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
3
{
720
3
    Py_ssize_t length = 0;
721
3
    PyObject *result, *it = NULL;
722
723
3
    result = PyList_New(0);
724
3
    if (result == NULL)
725
0
        return NULL;
726
727
3
    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
3
        PyObject *ret = PyObject_CallMethodObjArgs(result, &_Py_ID(extend),
732
3
                                                   self, NULL);
733
3
        if (ret == NULL) {
734
0
            goto error;
735
0
        }
736
3
        Py_DECREF(ret);
737
3
        return result;
738
3
    }
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
};