Coverage Report

Created: 2025-07-11 06:59

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