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