LCOV - code coverage report
Current view: top level - Modules/_io - iobase.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit 5e6661bce9] Lines: 104 344 30.2 %
Date: 2023-03-20 08:15:36 Functions: 16 34 47.1 %
Branches: 35 190 18.4 %

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

Generated by: LCOV version 1.14