LCOV - code coverage report
Current view: top level - Modules/_io - iobase.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 290 346 83.8 %
Date: 2022-07-20 13:12:14 Functions: 32 34 94.1 %
Branches: 143 190 75.3 %

           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                 :       1423 : iobase_unsupported(const char *message)
      75                 :            : {
      76                 :       1423 :     _PyIO_State *state = IO_STATE();
      77         [ +  - ]:       1423 :     if (state != NULL)
      78                 :       1423 :         PyErr_SetString(state->unsupported_operation, message);
      79                 :       1423 :     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                 :       1393 : iobase_seek(PyObject *self, PyObject *args)
      99                 :            : {
     100                 :       1393 :     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                 :       7939 : _io__IOBase_tell_impl(PyObject *self)
     111                 :            : /*[clinic end generated code: output=89a1c0807935abe2 input=04e615fec128801f]*/
     112                 :            : {
     113                 :       7939 :     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                 :          2 : iobase_truncate(PyObject *self, PyObject *args)
     124                 :            : {
     125                 :          2 :     return iobase_unsupported("truncate");
     126                 :            : }
     127                 :            : 
     128                 :            : static int
     129                 :    1455758 : 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                 :    1455758 :     ret = _PyObject_LookupAttr(self, &_Py_ID(__IOBase_closed), &res);
     136                 :    1455758 :     Py_XDECREF(res);
     137                 :    1455758 :     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                 :     626357 : _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                 :     626357 :     int closed = iobase_is_closed(self);
     156                 :            : 
     157         [ +  + ]:     626357 :     if (!closed) {
     158                 :     626350 :         Py_RETURN_NONE;
     159                 :            :     }
     160         [ +  - ]:          7 :     if (closed > 0) {
     161                 :          7 :         PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
     162                 :            :     }
     163                 :          7 :     return NULL;
     164                 :            : }
     165                 :            : 
     166                 :            : static PyObject *
     167                 :     489108 : iobase_closed_get(PyObject *self, void *context)
     168                 :            : {
     169                 :     489108 :     int closed = iobase_is_closed(self);
     170         [ -  + ]:     489108 :     if (closed < 0) {
     171                 :          0 :         return NULL;
     172                 :            :     }
     173                 :     489108 :     return PyBool_FromLong(closed);
     174                 :            : }
     175                 :            : 
     176                 :            : static int
     177                 :     465365 : 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                 :     465365 :     closed = _PyObject_LookupAttr(self, &_Py_ID(closed), &res);
     184         [ +  - ]:     465365 :     if (closed > 0) {
     185                 :     465365 :         closed = PyObject_IsTrue(res);
     186                 :     465365 :         Py_DECREF(res);
     187         [ +  + ]:     465365 :         if (closed > 0) {
     188                 :         82 :             PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
     189                 :         82 :             return -1;
     190                 :            :         }
     191                 :            :     }
     192                 :     465283 :     return closed;
     193                 :            : }
     194                 :            : 
     195                 :            : PyObject *
     196                 :      25956 : _PyIOBase_check_closed(PyObject *self, PyObject *args)
     197                 :            : {
     198         [ +  + ]:      25956 :     if (iobase_check_closed(self)) {
     199                 :          7 :         return NULL;
     200                 :            :     }
     201         [ +  + ]:      25949 :     if (args == Py_True) {
     202                 :      17970 :         return Py_None;
     203                 :            :     }
     204                 :       7979 :     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                 :     340293 : _io__IOBase_close_impl(PyObject *self)
     221                 :            : /*[clinic end generated code: output=63c6a6f57d783d6d input=f4494d5c31dbc6b7]*/
     222                 :            : {
     223                 :            :     PyObject *res, *exc, *val, *tb;
     224                 :     340293 :     int rc, closed = iobase_is_closed(self);
     225                 :            : 
     226         [ -  + ]:     340293 :     if (closed < 0) {
     227                 :          0 :         return NULL;
     228                 :            :     }
     229         [ +  + ]:     340293 :     if (closed) {
     230                 :         87 :         Py_RETURN_NONE;
     231                 :            :     }
     232                 :            : 
     233                 :     340206 :     res = PyObject_CallMethodNoArgs(self, &_Py_ID(flush));
     234                 :            : 
     235                 :     340206 :     PyErr_Fetch(&exc, &val, &tb);
     236                 :     340206 :     rc = PyObject_SetAttr(self, &_Py_ID(__IOBase_closed), Py_True);
     237                 :     340206 :     _PyErr_ChainExceptions(exc, val, tb);
     238         [ -  + ]:     340206 :     if (rc < 0) {
     239         [ #  # ]:          0 :         Py_CLEAR(res);
     240                 :            :     }
     241                 :            : 
     242         [ +  + ]:     340206 :     if (res == NULL)
     243                 :          9 :         return NULL;
     244                 :            : 
     245                 :     340197 :     Py_DECREF(res);
     246                 :     340197 :     Py_RETURN_NONE;
     247                 :            : }
     248                 :            : 
     249                 :            : /* Finalization and garbage collection support */
     250                 :            : 
     251                 :            : static void
     252                 :     726226 : 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                 :     726226 :     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         [ +  + ]:     726226 :     if (_PyObject_LookupAttr(self, &_Py_ID(closed), &res) <= 0) {
     264                 :        608 :         PyErr_Clear();
     265                 :        608 :         closed = -1;
     266                 :            :     }
     267                 :            :     else {
     268                 :     725618 :         closed = PyObject_IsTrue(res);
     269                 :     725618 :         Py_DECREF(res);
     270         [ -  + ]:     725618 :         if (closed == -1)
     271                 :          0 :             PyErr_Clear();
     272                 :            :     }
     273         [ +  + ]:     726226 :     if (closed == 0) {
     274                 :            :         /* Signal close() that it was called as part of the object
     275                 :            :            finalization process. */
     276         [ -  + ]:      33782 :         if (PyObject_SetAttr(self, &_Py_ID(_finalizing), Py_True))
     277                 :          0 :             PyErr_Clear();
     278                 :      33782 :         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         [ +  + ]:      33782 :         if (res == NULL) {
     283                 :            : #ifndef Py_DEBUG
     284         [ -  + ]:          8 :             if (_Py_GetConfig()->dev_mode) {
     285                 :          0 :                 PyErr_WriteUnraisable(self);
     286                 :            :             }
     287                 :            :             else {
     288                 :          8 :                 PyErr_Clear();
     289                 :            :             }
     290                 :            : #else
     291                 :            :             PyErr_WriteUnraisable(self);
     292                 :            : #endif
     293                 :            :         }
     294                 :            :         else {
     295                 :      33774 :             Py_DECREF(res);
     296                 :            :         }
     297                 :            :     }
     298                 :            : 
     299                 :            :     /* Restore the saved exception. */
     300                 :     726226 :     PyErr_Restore(error_type, error_value, error_traceback);
     301                 :     726226 : }
     302                 :            : 
     303                 :            : int
     304                 :     722754 : _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                 :     722754 :     is_zombie = (Py_REFCNT(self) == 0);
     311         [ +  - ]:     722754 :     if (is_zombie)
     312                 :     722754 :         return PyObject_CallFinalizerFromDealloc(self);
     313                 :            :     else {
     314                 :          0 :         PyObject_CallFinalizer(self);
     315                 :          0 :         return 0;
     316                 :            :     }
     317                 :            : }
     318                 :            : 
     319                 :            : static int
     320                 :       9360 : iobase_traverse(iobase *self, visitproc visit, void *arg)
     321                 :            : {
     322   [ +  +  -  + ]:       9360 :     Py_VISIT(self->dict);
     323                 :       9360 :     return 0;
     324                 :            : }
     325                 :            : 
     326                 :            : static int
     327                 :        133 : iobase_clear(iobase *self)
     328                 :            : {
     329         [ +  - ]:        133 :     Py_CLEAR(self->dict);
     330                 :        133 :     return 0;
     331                 :            : }
     332                 :            : 
     333                 :            : /* Destructor */
     334                 :            : 
     335                 :            : static void
     336                 :      47253 : 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         [ -  + ]:      47253 :     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         [ #  # ]:          0 :         if (_PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE)) {
     347                 :          0 :             Py_INCREF(Py_TYPE(self));
     348                 :            :         }
     349                 :          0 :         return;
     350                 :            :     }
     351                 :      47253 :     _PyObject_GC_UNTRACK(self);
     352         [ -  + ]:      47253 :     if (self->weakreflist != NULL)
     353                 :          0 :         PyObject_ClearWeakRefs((PyObject *) self);
     354         [ +  + ]:      47253 :     Py_CLEAR(self->dict);
     355                 :      47253 :     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 *
     370                 :       2261 : _io__IOBase_seekable_impl(PyObject *self)
     371                 :            : /*[clinic end generated code: output=4c24c67f5f32a43d input=b976622f7fdf3063]*/
     372                 :            : {
     373                 :       2261 :     Py_RETURN_FALSE;
     374                 :            : }
     375                 :            : 
     376                 :            : PyObject *
     377                 :     115310 : _PyIOBase_check_seekable(PyObject *self, PyObject *args)
     378                 :            : {
     379                 :     115310 :     PyObject *res  = PyObject_CallMethodNoArgs(self, &_Py_ID(seekable));
     380         [ -  + ]:     115310 :     if (res == NULL)
     381                 :          0 :         return NULL;
     382         [ +  + ]:     115310 :     if (res != Py_True) {
     383         [ +  - ]:          5 :         Py_CLEAR(res);
     384                 :          5 :         iobase_unsupported("File or stream is not seekable.");
     385                 :          5 :         return NULL;
     386                 :            :     }
     387         [ +  + ]:     115305 :     if (args == Py_True) {
     388                 :     115304 :         Py_DECREF(res);
     389                 :            :     }
     390                 :     115305 :     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 *
     402                 :      19880 : _io__IOBase_readable_impl(PyObject *self)
     403                 :            : /*[clinic end generated code: output=e48089250686388b input=285b3b866a0ec35f]*/
     404                 :            : {
     405                 :      19880 :     Py_RETURN_FALSE;
     406                 :            : }
     407                 :            : 
     408                 :            : /* May be called with any object */
     409                 :            : PyObject *
     410                 :     277680 : _PyIOBase_check_readable(PyObject *self, PyObject *args)
     411                 :            : {
     412                 :     277680 :     PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(readable));
     413         [ -  + ]:     277680 :     if (res == NULL)
     414                 :          0 :         return NULL;
     415         [ +  + ]:     277680 :     if (res != Py_True) {
     416         [ +  - ]:          1 :         Py_CLEAR(res);
     417                 :          1 :         iobase_unsupported("File or stream is not readable.");
     418                 :          1 :         return NULL;
     419                 :            :     }
     420         [ +  + ]:     277679 :     if (args == Py_True) {
     421                 :     269905 :         Py_DECREF(res);
     422                 :            :     }
     423                 :     277679 :     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 *
     435                 :      12296 : _io__IOBase_writable_impl(PyObject *self)
     436                 :            : /*[clinic end generated code: output=406001d0985be14f input=9dcac18a013a05b5]*/
     437                 :            : {
     438                 :      12296 :     Py_RETURN_FALSE;
     439                 :            : }
     440                 :            : 
     441                 :            : /* May be called with any object */
     442                 :            : PyObject *
     443                 :      63086 : _PyIOBase_check_writable(PyObject *self, PyObject *args)
     444                 :            : {
     445                 :      63086 :     PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(writable));
     446         [ -  + ]:      63086 :     if (res == NULL)
     447                 :          0 :         return NULL;
     448         [ +  + ]:      63086 :     if (res != Py_True) {
     449         [ +  - ]:          1 :         Py_CLEAR(res);
     450                 :          1 :         iobase_unsupported("File or stream is not writable.");
     451                 :          1 :         return NULL;
     452                 :            :     }
     453         [ +  + ]:      63085 :     if (args == Py_True) {
     454                 :      62908 :         Py_DECREF(res);
     455                 :            :     }
     456                 :      63085 :     return res;
     457                 :            : }
     458                 :            : 
     459                 :            : /* Context manager */
     460                 :            : 
     461                 :            : static PyObject *
     462                 :     277880 : iobase_enter(PyObject *self, PyObject *args)
     463                 :            : {
     464         [ +  + ]:     277880 :     if (iobase_check_closed(self))
     465                 :          6 :         return NULL;
     466                 :            : 
     467                 :     277874 :     Py_INCREF(self);
     468                 :     277874 :     return self;
     469                 :            : }
     470                 :            : 
     471                 :            : static PyObject *
     472                 :     277801 : iobase_exit(PyObject *self, PyObject *args)
     473                 :            : {
     474                 :     277801 :     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 *
     490                 :         21 : _io__IOBase_fileno_impl(PyObject *self)
     491                 :            : /*[clinic end generated code: output=7cc0973f0f5f3b73 input=4e37028947dc1cc8]*/
     492                 :            : {
     493                 :         21 :     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 *
     505                 :          3 : _io__IOBase_isatty_impl(PyObject *self)
     506                 :            : /*[clinic end generated code: output=60cab77cede41cdd input=9ef76530d368458b]*/
     507                 :            : {
     508         [ +  + ]:          3 :     if (iobase_check_closed(self))
     509                 :          1 :         return NULL;
     510                 :          2 :     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 *
     530                 :       2335 : _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                 :       2335 :     Py_ssize_t old_size = -1;
     537                 :            : 
     538         [ -  + ]:       2335 :     if (_PyObject_LookupAttr(self, &_Py_ID(peek), &peek) < 0) {
     539                 :          0 :         return NULL;
     540                 :            :     }
     541                 :            : 
     542                 :       2335 :     buffer = PyByteArray_FromStringAndSize(NULL, 0);
     543         [ -  + ]:       2335 :     if (buffer == NULL) {
     544                 :          0 :         Py_XDECREF(peek);
     545                 :          0 :         return NULL;
     546                 :            :     }
     547                 :            : 
     548   [ +  +  +  + ]:       4318 :     while (limit < 0 || PyByteArray_GET_SIZE(buffer) < limit) {
     549                 :       4307 :         Py_ssize_t nreadahead = 1;
     550                 :            :         PyObject *b;
     551                 :            : 
     552         [ +  + ]:       4307 :         if (peek != NULL) {
     553                 :       2482 :             PyObject *readahead = PyObject_CallOneArg(peek, _PyLong_GetOne());
     554         [ -  + ]:       2482 :             if (readahead == NULL) {
     555                 :            :                 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
     556                 :            :                    when EINTR occurs so we needn't do it ourselves. */
     557         [ #  # ]:          0 :                 if (_PyIO_trap_eintr()) {
     558                 :          0 :                     continue;
     559                 :            :                 }
     560                 :          0 :                 goto fail;
     561                 :            :             }
     562         [ -  + ]:       2482 :             if (!PyBytes_Check(readahead)) {
     563                 :          0 :                 PyErr_Format(PyExc_OSError,
     564                 :            :                              "peek() should have returned a bytes object, "
     565                 :          0 :                              "not '%.200s'", Py_TYPE(readahead)->tp_name);
     566                 :          0 :                 Py_DECREF(readahead);
     567                 :          0 :                 goto fail;
     568                 :            :             }
     569         [ +  + ]:       2482 :             if (PyBytes_GET_SIZE(readahead) > 0) {
     570                 :       2464 :                 Py_ssize_t n = 0;
     571                 :       2464 :                 const char *buf = PyBytes_AS_STRING(readahead);
     572         [ +  + ]:       2464 :                 if (limit >= 0) {
     573                 :            :                     do {
     574   [ +  +  +  + ]:      75284 :                         if (n >= PyBytes_GET_SIZE(readahead) || n >= limit)
     575                 :            :                             break;
     576         [ +  + ]:      75255 :                         if (buf[n++] == '\n')
     577                 :       1915 :                             break;
     578                 :            :                     } while (1);
     579                 :            :                 }
     580                 :            :                 else {
     581                 :            :                     do {
     582         [ +  + ]:      12800 :                         if (n >= PyBytes_GET_SIZE(readahead))
     583                 :        235 :                             break;
     584         [ +  + ]:      12565 :                         if (buf[n++] == '\n')
     585                 :        285 :                             break;
     586                 :            :                     } while (1);
     587                 :            :                 }
     588                 :       2464 :                 nreadahead = n;
     589                 :            :             }
     590                 :       2482 :             Py_DECREF(readahead);
     591                 :            :         }
     592                 :            : 
     593                 :       4307 :         b = _PyObject_CallMethod(self, &_Py_ID(read), "n", nreadahead);
     594         [ +  + ]:       4307 :         if (b == NULL) {
     595                 :            :             /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
     596                 :            :                when EINTR occurs so we needn't do it ourselves. */
     597         [ -  + ]:         13 :             if (_PyIO_trap_eintr()) {
     598                 :          0 :                 continue;
     599                 :            :             }
     600                 :         13 :             goto fail;
     601                 :            :         }
     602         [ -  + ]:       4294 :         if (!PyBytes_Check(b)) {
     603                 :          0 :             PyErr_Format(PyExc_OSError,
     604                 :            :                          "read() should have returned a bytes object, "
     605                 :          0 :                          "not '%.200s'", Py_TYPE(b)->tp_name);
     606                 :          0 :             Py_DECREF(b);
     607                 :          0 :             goto fail;
     608                 :            :         }
     609         [ +  + ]:       4294 :         if (PyBytes_GET_SIZE(b) == 0) {
     610                 :         27 :             Py_DECREF(b);
     611                 :         27 :             break;
     612                 :            :         }
     613                 :            : 
     614                 :       4267 :         old_size = PyByteArray_GET_SIZE(buffer);
     615         [ -  + ]:       4267 :         if (PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b)) < 0) {
     616                 :          0 :             Py_DECREF(b);
     617                 :          0 :             goto fail;
     618                 :            :         }
     619                 :       4267 :         memcpy(PyByteArray_AS_STRING(buffer) + old_size,
     620                 :       4267 :                PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b));
     621                 :            : 
     622                 :       4267 :         Py_DECREF(b);
     623                 :            : 
     624         [ +  + ]:       4267 :         if (PyByteArray_AS_STRING(buffer)[PyByteArray_GET_SIZE(buffer) - 1] == '\n')
     625                 :       2284 :             break;
     626                 :            :     }
     627                 :            : 
     628                 :       2322 :     result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(buffer),
     629                 :            :                                        PyByteArray_GET_SIZE(buffer));
     630                 :       2322 :     Py_XDECREF(peek);
     631                 :       2322 :     Py_DECREF(buffer);
     632                 :       2322 :     return result;
     633                 :         13 :   fail:
     634                 :         13 :     Py_XDECREF(peek);
     635                 :         13 :     Py_DECREF(buffer);
     636                 :         13 :     return NULL;
     637                 :            : }
     638                 :            : 
     639                 :            : static PyObject *
     640                 :      10420 : iobase_iter(PyObject *self)
     641                 :            : {
     642         [ +  + ]:      10420 :     if (iobase_check_closed(self))
     643                 :         49 :         return NULL;
     644                 :            : 
     645                 :      10371 :     Py_INCREF(self);
     646                 :      10371 :     return self;
     647                 :            : }
     648                 :            : 
     649                 :            : static PyObject *
     650                 :      25103 : iobase_iternext(PyObject *self)
     651                 :            : {
     652                 :      25103 :     PyObject *line = PyObject_CallMethodNoArgs(self, &_Py_ID(readline));
     653                 :            : 
     654         [ +  + ]:      25103 :     if (line == NULL)
     655                 :          7 :         return NULL;
     656                 :            : 
     657         [ +  + ]:      25096 :     if (PyObject_Size(line) <= 0) {
     658                 :            :         /* Error or empty */
     659                 :         44 :         Py_DECREF(line);
     660                 :         44 :         return NULL;
     661                 :            :     }
     662                 :            : 
     663                 :      25052 :     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 *
     679                 :       7367 : _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint)
     680                 :            : /*[clinic end generated code: output=2f50421677fa3dea input=9400c786ea9dc416]*/
     681                 :            : {
     682                 :       7367 :     Py_ssize_t length = 0;
     683                 :       7367 :     PyObject *result, *it = NULL;
     684                 :            : 
     685                 :       7367 :     result = PyList_New(0);
     686         [ -  + ]:       7367 :     if (result == NULL)
     687                 :          0 :         return NULL;
     688                 :            : 
     689         [ +  + ]:       7367 :     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                 :       7297 :         PyObject *ret = PyObject_CallMethodObjArgs(result, &_Py_ID(extend),
     694                 :            :                                                    self, NULL);
     695         [ +  + ]:       7293 :         if (ret == NULL) {
     696                 :         21 :             goto error;
     697                 :            :         }
     698                 :       7272 :         Py_DECREF(ret);
     699                 :       7272 :         return result;
     700                 :            :     }
     701                 :            : 
     702                 :         70 :     it = PyObject_GetIter(self);
     703         [ +  + ]:         70 :     if (it == NULL) {
     704                 :         15 :         goto error;
     705                 :            :     }
     706                 :            : 
     707                 :        227 :     while (1) {
     708                 :            :         Py_ssize_t line_length;
     709                 :        282 :         PyObject *line = PyIter_Next(it);
     710         [ +  + ]:        282 :         if (line == NULL) {
     711         [ -  + ]:         10 :             if (PyErr_Occurred()) {
     712                 :          0 :                 goto error;
     713                 :            :             }
     714                 :            :             else
     715                 :         10 :                 break; /* StopIteration raised */
     716                 :            :         }
     717                 :            : 
     718         [ -  + ]:        272 :         if (PyList_Append(result, line) < 0) {
     719                 :          0 :             Py_DECREF(line);
     720                 :          0 :             goto error;
     721                 :            :         }
     722                 :        272 :         line_length = PyObject_Size(line);
     723                 :        272 :         Py_DECREF(line);
     724         [ +  + ]:        272 :         if (line_length < 0) {
     725                 :          1 :             goto error;
     726                 :            :         }
     727         [ +  + ]:        271 :         if (line_length > hint - length)
     728                 :         44 :             break;
     729                 :        227 :         length += line_length;
     730                 :            :     }
     731                 :            : 
     732                 :         54 :     Py_DECREF(it);
     733                 :         54 :     return result;
     734                 :            : 
     735                 :         37 :  error:
     736                 :         37 :     Py_XDECREF(it);
     737                 :         37 :     Py_DECREF(result);
     738                 :         37 :     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 *
     753                 :     151106 : _io__IOBase_writelines(PyObject *self, PyObject *lines)
     754                 :            : /*[clinic end generated code: output=976eb0a9b60a6628 input=cac3fc8864183359]*/
     755                 :            : {
     756                 :            :     PyObject *iter, *res;
     757                 :            : 
     758         [ +  + ]:     151106 :     if (iobase_check_closed(self))
     759                 :         19 :         return NULL;
     760                 :            : 
     761                 :     151087 :     iter = PyObject_GetIter(lines);
     762         [ +  + ]:     151087 :     if (iter == NULL)
     763                 :          8 :         return NULL;
     764                 :            : 
     765                 :     455460 :     while (1) {
     766                 :     606539 :         PyObject *line = PyIter_Next(iter);
     767         [ +  + ]:     606539 :         if (line == NULL) {
     768         [ +  + ]:     151060 :             if (PyErr_Occurred()) {
     769                 :          1 :                 Py_DECREF(iter);
     770                 :          1 :                 return NULL;
     771                 :            :             }
     772                 :            :             else
     773                 :     151059 :                 break; /* Stop Iteration */
     774                 :            :         }
     775                 :            : 
     776                 :     455479 :         res = NULL;
     777                 :            :         do {
     778                 :     455479 :             res = PyObject_CallMethodObjArgs(self, &_Py_ID(write), line, NULL);
     779   [ +  +  -  + ]:     455479 :         } while (res == NULL && _PyIO_trap_eintr());
     780                 :     455479 :         Py_DECREF(line);
     781         [ +  + ]:     455479 :         if (res == NULL) {
     782                 :         19 :             Py_DECREF(iter);
     783                 :         19 :             return NULL;
     784                 :            :         }
     785                 :     455460 :         Py_DECREF(res);
     786                 :            :     }
     787                 :     151059 :     Py_DECREF(iter);
     788                 :     151059 :     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 *
     907                 :       3814 : _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         [ +  + ]:       3814 :     if (n < 0) {
     913                 :          3 :         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                 :       3811 :     b = PyByteArray_FromStringAndSize(NULL, n);
     919         [ -  + ]:       3811 :     if (b == NULL)
     920                 :          0 :         return NULL;
     921                 :            : 
     922                 :       3811 :     res = PyObject_CallMethodObjArgs(self, &_Py_ID(readinto), b, NULL);
     923   [ +  +  +  + ]:       3811 :     if (res == NULL || res == Py_None) {
     924                 :          6 :         Py_DECREF(b);
     925                 :          6 :         return res;
     926                 :            :     }
     927                 :            : 
     928                 :       3805 :     n = PyNumber_AsSsize_t(res, PyExc_ValueError);
     929                 :       3805 :     Py_DECREF(res);
     930   [ -  +  -  - ]:       3805 :     if (n == -1 && PyErr_Occurred()) {
     931                 :          0 :         Py_DECREF(b);
     932                 :          0 :         return NULL;
     933                 :            :     }
     934                 :            : 
     935                 :       3805 :     res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n);
     936                 :       3805 :     Py_DECREF(b);
     937                 :       3805 :     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 *
     948                 :         59 : _io__RawIOBase_readall_impl(PyObject *self)
     949                 :            : /*[clinic end generated code: output=1987b9ce929425a0 input=688874141213622a]*/
     950                 :            : {
     951                 :            :     int r;
     952                 :         59 :     PyObject *chunks = PyList_New(0);
     953                 :            :     PyObject *result;
     954                 :            : 
     955         [ +  - ]:         59 :     if (chunks == NULL)
     956                 :          0 :         return NULL;
     957                 :            : 
     958                 :       2089 :     while (1) {
     959                 :       2148 :         PyObject *data = _PyObject_CallMethod(self, &_Py_ID(read),
     960                 :            :                                               "i", DEFAULT_BUFFER_SIZE);
     961         [ -  + ]:       2148 :         if (!data) {
     962                 :            :             /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
     963                 :            :                when EINTR occurs so we needn't do it ourselves. */
     964         [ #  # ]:          0 :             if (_PyIO_trap_eintr()) {
     965                 :          0 :                 continue;
     966                 :            :             }
     967                 :          0 :             Py_DECREF(chunks);
     968                 :          0 :             return NULL;
     969                 :            :         }
     970         [ +  + ]:       2148 :         if (data == Py_None) {
     971         [ +  + ]:          8 :             if (PyList_GET_SIZE(chunks) == 0) {
     972                 :          6 :                 Py_DECREF(chunks);
     973                 :          6 :                 return data;
     974                 :            :             }
     975                 :          2 :             Py_DECREF(data);
     976                 :          2 :             break;
     977                 :            :         }
     978         [ -  + ]:       2140 :         if (!PyBytes_Check(data)) {
     979                 :          0 :             Py_DECREF(chunks);
     980                 :          0 :             Py_DECREF(data);
     981                 :          0 :             PyErr_SetString(PyExc_TypeError, "read() should return bytes");
     982                 :          0 :             return NULL;
     983                 :            :         }
     984         [ +  + ]:       2140 :         if (PyBytes_GET_SIZE(data) == 0) {
     985                 :            :             /* EOF */
     986                 :         51 :             Py_DECREF(data);
     987                 :         51 :             break;
     988                 :            :         }
     989                 :       2089 :         r = PyList_Append(chunks, data);
     990                 :       2089 :         Py_DECREF(data);
     991         [ -  + ]:       2089 :         if (r < 0) {
     992                 :          0 :             Py_DECREF(chunks);
     993                 :          0 :             return NULL;
     994                 :            :         }
     995                 :            :     }
     996                 :         53 :     result = _PyBytes_Join((PyObject *)&_Py_SINGLETON(bytes_empty), chunks);
     997                 :         53 :     Py_DECREF(chunks);
     998                 :         53 :     return result;
     999                 :            : }
    1000                 :            : 
    1001                 :            : static PyObject *
    1002                 :          0 : rawiobase_readinto(PyObject *self, PyObject *args)
    1003                 :            : {
    1004                 :          0 :     PyErr_SetNone(PyExc_NotImplementedError);
    1005                 :          0 :     return NULL;
    1006                 :            : }
    1007                 :            : 
    1008                 :            : static PyObject *
    1009                 :          0 : rawiobase_write(PyObject *self, PyObject *args)
    1010                 :            : {
    1011                 :          0 :     PyErr_SetNone(PyExc_NotImplementedError);
    1012                 :          0 :     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                 :            : };

Generated by: LCOV version 1.14