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