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]
19 module _io
20 class _io._IOBase "PyObject *" "&PyIOBase_Type"
21 class _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 
29 typedef struct {
30     PyObject_HEAD
31 
32     PyObject *dict;
33     PyObject *weakreflist;
34 } iobase;
35 
36 PyDoc_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 */
73 static PyObject *
iobase_unsupported(const char * message)74 iobase_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 
84 PyDoc_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 
97 static PyObject *
iobase_seek(PyObject * self,PyObject * args)98 iobase_seek(PyObject *self, PyObject *args)
99 {
100     return iobase_unsupported("seek");
101 }
102 
103 /*[clinic input]
104 _io._IOBase.tell
105 
106 Return current stream position.
107 [clinic start generated code]*/
108 
109 static PyObject *
_io__IOBase_tell_impl(PyObject * self)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 
116 PyDoc_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 
122 static PyObject *
iobase_truncate(PyObject * self,PyObject * args)123 iobase_truncate(PyObject *self, PyObject *args)
124 {
125     return iobase_unsupported("truncate");
126 }
127 
128 static int
iobase_is_closed(PyObject * self)129 iobase_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 
145 Flush write buffers, if applicable.
146 
147 This is not implemented for read-only and non-blocking streams.
148 [clinic start generated code]*/
149 
150 static PyObject *
_io__IOBase_flush_impl(PyObject * self)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 
166 static PyObject *
iobase_closed_get(PyObject * self,void * context)167 iobase_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 
176 static int
iobase_check_closed(PyObject * self)177 iobase_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 
195 PyObject *
_PyIOBase_check_closed(PyObject * self,PyObject * args)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 
214 Flush and close the IO object.
215 
216 This method has no effect if the file is already closed.
217 [clinic start generated code]*/
218 
219 static PyObject *
_io__IOBase_close_impl(PyObject * self)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 
251 static void
iobase_finalize(PyObject * self)252 iobase_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 
303 int
_PyIOBase_finalize(PyObject * self)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 
319 static int
iobase_traverse(iobase * self,visitproc visit,void * arg)320 iobase_traverse(iobase *self, visitproc visit, void *arg)
321 {
322     Py_VISIT(self->dict);
323     return 0;
324 }
325 
326 static int
iobase_clear(iobase * self)327 iobase_clear(iobase *self)
328 {
329     Py_CLEAR(self->dict);
330     return 0;
331 }
332 
333 /* Destructor */
334 
335 static void
iobase_dealloc(iobase * self)336 iobase_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 
363 Return whether object supports random access.
364 
365 If False, seek(), tell() and truncate() will raise OSError.
366 This method may need to do a test seek().
367 [clinic start generated code]*/
368 
369 static PyObject *
_io__IOBase_seekable_impl(PyObject * self)370 _io__IOBase_seekable_impl(PyObject *self)
371 /*[clinic end generated code: output=4c24c67f5f32a43d input=b976622f7fdf3063]*/
372 {
373     Py_RETURN_FALSE;
374 }
375 
376 PyObject *
_PyIOBase_check_seekable(PyObject * self,PyObject * args)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 
396 Return whether object was opened for reading.
397 
398 If False, read() will raise OSError.
399 [clinic start generated code]*/
400 
401 static PyObject *
_io__IOBase_readable_impl(PyObject * self)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 */
409 PyObject *
_PyIOBase_check_readable(PyObject * self,PyObject * args)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 
429 Return whether object was opened for writing.
430 
431 If False, write() will raise OSError.
432 [clinic start generated code]*/
433 
434 static PyObject *
_io__IOBase_writable_impl(PyObject * self)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 */
442 PyObject *
_PyIOBase_check_writable(PyObject * self,PyObject * args)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 
461 static PyObject *
iobase_enter(PyObject * self,PyObject * args)462 iobase_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 
471 static PyObject *
iobase_exit(PyObject * self,PyObject * args)472 iobase_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 
484 Returns underlying file descriptor if one exists.
485 
486 OSError is raised if the IO object does not use a file descriptor.
487 [clinic start generated code]*/
488 
489 static PyObject *
_io__IOBase_fileno_impl(PyObject * self)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 
499 Return whether this is an 'interactive' stream.
500 
501 Return False if it can't be determined.
502 [clinic start generated code]*/
503 
504 static PyObject *
_io__IOBase_isatty_impl(PyObject * self)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 
520 Read and return a line from the stream.
521 
522 If size is specified, at most size bytes will be read.
523 
524 The line terminator is always b'\n' for binary files; for text
525 files, the newlines argument to open can be used to select the line
526 terminator(s) recognized.
527 [clinic start generated code]*/
528 
529 static PyObject *
_io__IOBase_readline_impl(PyObject * self,Py_ssize_t limit)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 
639 static PyObject *
iobase_iter(PyObject * self)640 iobase_iter(PyObject *self)
641 {
642     if (iobase_check_closed(self))
643         return NULL;
644 
645     Py_INCREF(self);
646     return self;
647 }
648 
649 static PyObject *
iobase_iternext(PyObject * self)650 iobase_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 
671 Return a list of lines from the stream.
672 
673 hint can be specified to control the number of lines read: no more
674 lines will be read if the total size (in bytes/characters) of all
675 lines so far exceeds hint.
676 [clinic start generated code]*/
677 
678 static PyObject *
_io__IOBase_readlines_impl(PyObject * self,Py_ssize_t hint)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 
746 Write a list of lines to stream.
747 
748 Line separators are not added, so it is usual for each of the
749 lines provided to have a line separator at the end.
750 [clinic start generated code]*/
751 
752 static PyObject *
_io__IOBase_writelines(PyObject * self,PyObject * lines)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 
793 static 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 
822 static PyGetSetDef iobase_getset[] = {
823     {"__dict__", PyObject_GenericGetDict, NULL, NULL},
824     {"closed", (getter)iobase_closed_get, NULL, NULL},
825     {NULL}
826 };
827 
828 
829 PyTypeObject 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  */
885 PyDoc_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 
906 static PyObject *
_io__RawIOBase_read_impl(PyObject * self,Py_ssize_t n)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 
944 Read until EOF, using multiple read() call.
945 [clinic start generated code]*/
946 
947 static PyObject *
_io__RawIOBase_readall_impl(PyObject * self)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 
1001 static PyObject *
rawiobase_readinto(PyObject * self,PyObject * args)1002 rawiobase_readinto(PyObject *self, PyObject *args)
1003 {
1004     PyErr_SetNone(PyExc_NotImplementedError);
1005     return NULL;
1006 }
1007 
1008 static PyObject *
rawiobase_write(PyObject * self,PyObject * args)1009 rawiobase_write(PyObject *self, PyObject *args)
1010 {
1011     PyErr_SetNone(PyExc_NotImplementedError);
1012     return NULL;
1013 }
1014 
1015 static 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 
1023 PyTypeObject 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