LCOV - code coverage report
Current view: top level - Objects - iterobject.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit 5e6661bce9] Lines: 60 164 36.6 %
Date: 2023-03-20 08:15:36 Functions: 7 21 33.3 %
Branches: 20 100 20.0 %

           Branch data     Line data    Source code
       1                 :            : /* Iterator objects */
       2                 :            : 
       3                 :            : #include "Python.h"
       4                 :            : #include "pycore_call.h"          // _PyObject_CallNoArgs()
       5                 :            : #include "pycore_object.h"        // _PyObject_GC_TRACK()
       6                 :            : 
       7                 :            : typedef struct {
       8                 :            :     PyObject_HEAD
       9                 :            :     Py_ssize_t it_index;
      10                 :            :     PyObject *it_seq; /* Set to NULL when iterator is exhausted */
      11                 :            : } seqiterobject;
      12                 :            : 
      13                 :            : PyObject *
      14                 :        527 : PySeqIter_New(PyObject *seq)
      15                 :            : {
      16                 :            :     seqiterobject *it;
      17                 :            : 
      18         [ -  + ]:        527 :     if (!PySequence_Check(seq)) {
      19                 :          0 :         PyErr_BadInternalCall();
      20                 :          0 :         return NULL;
      21                 :            :     }
      22                 :        527 :     it = PyObject_GC_New(seqiterobject, &PySeqIter_Type);
      23         [ -  + ]:        527 :     if (it == NULL)
      24                 :          0 :         return NULL;
      25                 :        527 :     it->it_index = 0;
      26                 :        527 :     it->it_seq = Py_NewRef(seq);
      27                 :        527 :     _PyObject_GC_TRACK(it);
      28                 :        527 :     return (PyObject *)it;
      29                 :            : }
      30                 :            : 
      31                 :            : static void
      32                 :        527 : iter_dealloc(seqiterobject *it)
      33                 :            : {
      34                 :        527 :     _PyObject_GC_UNTRACK(it);
      35                 :        527 :     Py_XDECREF(it->it_seq);
      36                 :        527 :     PyObject_GC_Del(it);
      37                 :        527 : }
      38                 :            : 
      39                 :            : static int
      40                 :          0 : iter_traverse(seqiterobject *it, visitproc visit, void *arg)
      41                 :            : {
      42   [ #  #  #  # ]:          0 :     Py_VISIT(it->it_seq);
      43                 :          0 :     return 0;
      44                 :            : }
      45                 :            : 
      46                 :            : static PyObject *
      47                 :       1296 : iter_iternext(PyObject *iterator)
      48                 :            : {
      49                 :            :     seqiterobject *it;
      50                 :            :     PyObject *seq;
      51                 :            :     PyObject *result;
      52                 :            : 
      53                 :            :     assert(PySeqIter_Check(iterator));
      54                 :       1296 :     it = (seqiterobject *)iterator;
      55                 :       1296 :     seq = it->it_seq;
      56         [ -  + ]:       1296 :     if (seq == NULL)
      57                 :          0 :         return NULL;
      58         [ -  + ]:       1296 :     if (it->it_index == PY_SSIZE_T_MAX) {
      59                 :          0 :         PyErr_SetString(PyExc_OverflowError,
      60                 :            :                         "iter index too large");
      61                 :          0 :         return NULL;
      62                 :            :     }
      63                 :            : 
      64                 :       1296 :     result = PySequence_GetItem(seq, it->it_index);
      65         [ +  + ]:       1296 :     if (result != NULL) {
      66                 :        769 :         it->it_index++;
      67                 :        769 :         return result;
      68                 :            :     }
      69   [ -  +  -  - ]:        527 :     if (PyErr_ExceptionMatches(PyExc_IndexError) ||
      70                 :          0 :         PyErr_ExceptionMatches(PyExc_StopIteration))
      71                 :            :     {
      72                 :        527 :         PyErr_Clear();
      73                 :        527 :         it->it_seq = NULL;
      74                 :        527 :         Py_DECREF(seq);
      75                 :            :     }
      76                 :        527 :     return NULL;
      77                 :            : }
      78                 :            : 
      79                 :            : static PyObject *
      80                 :         15 : iter_len(seqiterobject *it, PyObject *Py_UNUSED(ignored))
      81                 :            : {
      82                 :            :     Py_ssize_t seqsize, len;
      83                 :            : 
      84         [ +  - ]:         15 :     if (it->it_seq) {
      85         [ +  - ]:         15 :         if (_PyObject_HasLen(it->it_seq)) {
      86                 :         15 :             seqsize = PySequence_Size(it->it_seq);
      87         [ -  + ]:         15 :             if (seqsize == -1)
      88                 :          0 :                 return NULL;
      89                 :            :         }
      90                 :            :         else {
      91                 :          0 :             Py_RETURN_NOTIMPLEMENTED;
      92                 :            :         }
      93                 :         15 :         len = seqsize - it->it_index;
      94         [ +  - ]:         15 :         if (len >= 0)
      95                 :         15 :             return PyLong_FromSsize_t(len);
      96                 :            :     }
      97                 :          0 :     return PyLong_FromLong(0);
      98                 :            : }
      99                 :            : 
     100                 :            : PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
     101                 :            : 
     102                 :            : static PyObject *
     103                 :          0 : iter_reduce(seqiterobject *it, PyObject *Py_UNUSED(ignored))
     104                 :            : {
     105                 :          0 :     PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter));
     106                 :            : 
     107                 :            :     /* _PyEval_GetBuiltin can invoke arbitrary code,
     108                 :            :      * call must be before access of iterator pointers.
     109                 :            :      * see issue #101765 */
     110                 :            : 
     111         [ #  # ]:          0 :     if (it->it_seq != NULL)
     112                 :          0 :         return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index);
     113                 :            :     else
     114                 :          0 :         return Py_BuildValue("N(())", iter);
     115                 :            : }
     116                 :            : 
     117                 :            : PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
     118                 :            : 
     119                 :            : static PyObject *
     120                 :          0 : iter_setstate(seqiterobject *it, PyObject *state)
     121                 :            : {
     122                 :          0 :     Py_ssize_t index = PyLong_AsSsize_t(state);
     123   [ #  #  #  # ]:          0 :     if (index == -1 && PyErr_Occurred())
     124                 :          0 :         return NULL;
     125         [ #  # ]:          0 :     if (it->it_seq != NULL) {
     126         [ #  # ]:          0 :         if (index < 0)
     127                 :          0 :             index = 0;
     128                 :          0 :         it->it_index = index;
     129                 :            :     }
     130                 :          0 :     Py_RETURN_NONE;
     131                 :            : }
     132                 :            : 
     133                 :            : PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
     134                 :            : 
     135                 :            : static PyMethodDef seqiter_methods[] = {
     136                 :            :     {"__length_hint__", (PyCFunction)iter_len, METH_NOARGS, length_hint_doc},
     137                 :            :     {"__reduce__", (PyCFunction)iter_reduce, METH_NOARGS, reduce_doc},
     138                 :            :     {"__setstate__", (PyCFunction)iter_setstate, METH_O, setstate_doc},
     139                 :            :     {NULL,              NULL}           /* sentinel */
     140                 :            : };
     141                 :            : 
     142                 :            : PyTypeObject PySeqIter_Type = {
     143                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     144                 :            :     "iterator",                                 /* tp_name */
     145                 :            :     sizeof(seqiterobject),                      /* tp_basicsize */
     146                 :            :     0,                                          /* tp_itemsize */
     147                 :            :     /* methods */
     148                 :            :     (destructor)iter_dealloc,                   /* tp_dealloc */
     149                 :            :     0,                                          /* tp_vectorcall_offset */
     150                 :            :     0,                                          /* tp_getattr */
     151                 :            :     0,                                          /* tp_setattr */
     152                 :            :     0,                                          /* tp_as_async */
     153                 :            :     0,                                          /* tp_repr */
     154                 :            :     0,                                          /* tp_as_number */
     155                 :            :     0,                                          /* tp_as_sequence */
     156                 :            :     0,                                          /* tp_as_mapping */
     157                 :            :     0,                                          /* tp_hash */
     158                 :            :     0,                                          /* tp_call */
     159                 :            :     0,                                          /* tp_str */
     160                 :            :     PyObject_GenericGetAttr,                    /* tp_getattro */
     161                 :            :     0,                                          /* tp_setattro */
     162                 :            :     0,                                          /* tp_as_buffer */
     163                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
     164                 :            :     0,                                          /* tp_doc */
     165                 :            :     (traverseproc)iter_traverse,                /* tp_traverse */
     166                 :            :     0,                                          /* tp_clear */
     167                 :            :     0,                                          /* tp_richcompare */
     168                 :            :     0,                                          /* tp_weaklistoffset */
     169                 :            :     PyObject_SelfIter,                          /* tp_iter */
     170                 :            :     iter_iternext,                              /* tp_iternext */
     171                 :            :     seqiter_methods,                            /* tp_methods */
     172                 :            :     0,                                          /* tp_members */
     173                 :            : };
     174                 :            : 
     175                 :            : /* -------------------------------------- */
     176                 :            : 
     177                 :            : typedef struct {
     178                 :            :     PyObject_HEAD
     179                 :            :     PyObject *it_callable; /* Set to NULL when iterator is exhausted */
     180                 :            :     PyObject *it_sentinel; /* Set to NULL when iterator is exhausted */
     181                 :            : } calliterobject;
     182                 :            : 
     183                 :            : PyObject *
     184                 :    1443749 : PyCallIter_New(PyObject *callable, PyObject *sentinel)
     185                 :            : {
     186                 :            :     calliterobject *it;
     187                 :    1443749 :     it = PyObject_GC_New(calliterobject, &PyCallIter_Type);
     188         [ -  + ]:    1443749 :     if (it == NULL)
     189                 :          0 :         return NULL;
     190                 :    1443749 :     it->it_callable = Py_NewRef(callable);
     191                 :    1443749 :     it->it_sentinel = Py_NewRef(sentinel);
     192                 :    1443749 :     _PyObject_GC_TRACK(it);
     193                 :    1443749 :     return (PyObject *)it;
     194                 :            : }
     195                 :            : static void
     196                 :    1443749 : calliter_dealloc(calliterobject *it)
     197                 :            : {
     198                 :    1443749 :     _PyObject_GC_UNTRACK(it);
     199                 :    1443749 :     Py_XDECREF(it->it_callable);
     200                 :    1443749 :     Py_XDECREF(it->it_sentinel);
     201                 :    1443749 :     PyObject_GC_Del(it);
     202                 :    1443749 : }
     203                 :            : 
     204                 :            : static int
     205                 :          0 : calliter_traverse(calliterobject *it, visitproc visit, void *arg)
     206                 :            : {
     207   [ #  #  #  # ]:          0 :     Py_VISIT(it->it_callable);
     208   [ #  #  #  # ]:          0 :     Py_VISIT(it->it_sentinel);
     209                 :          0 :     return 0;
     210                 :            : }
     211                 :            : 
     212                 :            : static PyObject *
     213                 :    1445532 : calliter_iternext(calliterobject *it)
     214                 :            : {
     215                 :            :     PyObject *result;
     216                 :            : 
     217         [ -  + ]:    1445532 :     if (it->it_callable == NULL) {
     218                 :          0 :         return NULL;
     219                 :            :     }
     220                 :            : 
     221                 :    1445532 :     result = _PyObject_CallNoArgs(it->it_callable);
     222   [ +  -  +  - ]:    2889281 :     if (result != NULL && it->it_sentinel != NULL){
     223                 :            :         int ok;
     224                 :            : 
     225                 :    1445532 :         ok = PyObject_RichCompareBool(it->it_sentinel, result, Py_EQ);
     226         [ +  + ]:    1445532 :         if (ok == 0) {
     227                 :       1783 :             return result; /* Common case, fast path */
     228                 :            :         }
     229                 :            : 
     230         [ +  - ]:    1443749 :         if (ok > 0) {
     231         [ +  - ]:    1443749 :             Py_CLEAR(it->it_callable);
     232         [ +  - ]:    1443749 :             Py_CLEAR(it->it_sentinel);
     233                 :            :         }
     234                 :            :     }
     235         [ #  # ]:          0 :     else if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
     236                 :          0 :         PyErr_Clear();
     237         [ #  # ]:          0 :         Py_CLEAR(it->it_callable);
     238         [ #  # ]:          0 :         Py_CLEAR(it->it_sentinel);
     239                 :            :     }
     240                 :    1443749 :     Py_XDECREF(result);
     241                 :    1443749 :     return NULL;
     242                 :            : }
     243                 :            : 
     244                 :            : static PyObject *
     245                 :          0 : calliter_reduce(calliterobject *it, PyObject *Py_UNUSED(ignored))
     246                 :            : {
     247                 :          0 :     PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter));
     248                 :            : 
     249                 :            :     /* _PyEval_GetBuiltin can invoke arbitrary code,
     250                 :            :      * call must be before access of iterator pointers.
     251                 :            :      * see issue #101765 */
     252                 :            : 
     253   [ #  #  #  # ]:          0 :     if (it->it_callable != NULL && it->it_sentinel != NULL)
     254                 :          0 :         return Py_BuildValue("N(OO)", iter, it->it_callable, it->it_sentinel);
     255                 :            :     else
     256                 :          0 :         return Py_BuildValue("N(())", iter);
     257                 :            : }
     258                 :            : 
     259                 :            : static PyMethodDef calliter_methods[] = {
     260                 :            :     {"__reduce__", (PyCFunction)calliter_reduce, METH_NOARGS, reduce_doc},
     261                 :            :     {NULL,              NULL}           /* sentinel */
     262                 :            : };
     263                 :            : 
     264                 :            : PyTypeObject PyCallIter_Type = {
     265                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     266                 :            :     "callable_iterator",                        /* tp_name */
     267                 :            :     sizeof(calliterobject),                     /* tp_basicsize */
     268                 :            :     0,                                          /* tp_itemsize */
     269                 :            :     /* methods */
     270                 :            :     (destructor)calliter_dealloc,               /* tp_dealloc */
     271                 :            :     0,                                          /* tp_vectorcall_offset */
     272                 :            :     0,                                          /* tp_getattr */
     273                 :            :     0,                                          /* tp_setattr */
     274                 :            :     0,                                          /* tp_as_async */
     275                 :            :     0,                                          /* tp_repr */
     276                 :            :     0,                                          /* tp_as_number */
     277                 :            :     0,                                          /* tp_as_sequence */
     278                 :            :     0,                                          /* tp_as_mapping */
     279                 :            :     0,                                          /* tp_hash */
     280                 :            :     0,                                          /* tp_call */
     281                 :            :     0,                                          /* tp_str */
     282                 :            :     PyObject_GenericGetAttr,                    /* tp_getattro */
     283                 :            :     0,                                          /* tp_setattro */
     284                 :            :     0,                                          /* tp_as_buffer */
     285                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
     286                 :            :     0,                                          /* tp_doc */
     287                 :            :     (traverseproc)calliter_traverse,            /* tp_traverse */
     288                 :            :     0,                                          /* tp_clear */
     289                 :            :     0,                                          /* tp_richcompare */
     290                 :            :     0,                                          /* tp_weaklistoffset */
     291                 :            :     PyObject_SelfIter,                          /* tp_iter */
     292                 :            :     (iternextfunc)calliter_iternext,            /* tp_iternext */
     293                 :            :     calliter_methods,                           /* tp_methods */
     294                 :            : };
     295                 :            : 
     296                 :            : 
     297                 :            : /* -------------------------------------- */
     298                 :            : 
     299                 :            : typedef struct {
     300                 :            :     PyObject_HEAD
     301                 :            :     PyObject *wrapped;
     302                 :            :     PyObject *default_value;
     303                 :            : } anextawaitableobject;
     304                 :            : 
     305                 :            : static void
     306                 :          0 : anextawaitable_dealloc(anextawaitableobject *obj)
     307                 :            : {
     308                 :          0 :     _PyObject_GC_UNTRACK(obj);
     309                 :          0 :     Py_XDECREF(obj->wrapped);
     310                 :          0 :     Py_XDECREF(obj->default_value);
     311                 :          0 :     PyObject_GC_Del(obj);
     312                 :          0 : }
     313                 :            : 
     314                 :            : static int
     315                 :          0 : anextawaitable_traverse(anextawaitableobject *obj, visitproc visit, void *arg)
     316                 :            : {
     317   [ #  #  #  # ]:          0 :     Py_VISIT(obj->wrapped);
     318   [ #  #  #  # ]:          0 :     Py_VISIT(obj->default_value);
     319                 :          0 :     return 0;
     320                 :            : }
     321                 :            : 
     322                 :            : static PyObject *
     323                 :          0 : anextawaitable_getiter(anextawaitableobject *obj)
     324                 :            : {
     325                 :            :     assert(obj->wrapped != NULL);
     326                 :          0 :     PyObject *awaitable = _PyCoro_GetAwaitableIter(obj->wrapped);
     327         [ #  # ]:          0 :     if (awaitable == NULL) {
     328                 :          0 :         return NULL;
     329                 :            :     }
     330         [ #  # ]:          0 :     if (Py_TYPE(awaitable)->tp_iternext == NULL) {
     331                 :            :         /* _PyCoro_GetAwaitableIter returns a Coroutine, a Generator,
     332                 :            :          * or an iterator. Of these, only coroutines lack tp_iternext.
     333                 :            :          */
     334                 :            :         assert(PyCoro_CheckExact(awaitable));
     335                 :          0 :         unaryfunc getter = Py_TYPE(awaitable)->tp_as_async->am_await;
     336                 :          0 :         PyObject *new_awaitable = getter(awaitable);
     337         [ #  # ]:          0 :         if (new_awaitable == NULL) {
     338                 :          0 :             Py_DECREF(awaitable);
     339                 :          0 :             return NULL;
     340                 :            :         }
     341                 :          0 :         Py_SETREF(awaitable, new_awaitable);
     342         [ #  # ]:          0 :         if (!PyIter_Check(awaitable)) {
     343                 :          0 :             PyErr_SetString(PyExc_TypeError,
     344                 :            :                             "__await__ returned a non-iterable");
     345                 :          0 :             Py_DECREF(awaitable);
     346                 :          0 :             return NULL;
     347                 :            :         }
     348                 :            :     }
     349                 :          0 :     return awaitable;
     350                 :            : }
     351                 :            : 
     352                 :            : static PyObject *
     353                 :          0 : anextawaitable_iternext(anextawaitableobject *obj)
     354                 :            : {
     355                 :            :     /* Consider the following class:
     356                 :            :      *
     357                 :            :      *     class A:
     358                 :            :      *         async def __anext__(self):
     359                 :            :      *             ...
     360                 :            :      *     a = A()
     361                 :            :      *
     362                 :            :      * Then `await anext(a)` should call
     363                 :            :      * a.__anext__().__await__().__next__()
     364                 :            :      *
     365                 :            :      * On the other hand, given
     366                 :            :      *
     367                 :            :      *     async def agen():
     368                 :            :      *         yield 1
     369                 :            :      *         yield 2
     370                 :            :      *     gen = agen()
     371                 :            :      *
     372                 :            :      * Then `await anext(gen)` can just call
     373                 :            :      * gen.__anext__().__next__()
     374                 :            :      */
     375                 :          0 :     PyObject *awaitable = anextawaitable_getiter(obj);
     376         [ #  # ]:          0 :     if (awaitable == NULL) {
     377                 :          0 :         return NULL;
     378                 :            :     }
     379                 :          0 :     PyObject *result = (*Py_TYPE(awaitable)->tp_iternext)(awaitable);
     380                 :          0 :     Py_DECREF(awaitable);
     381         [ #  # ]:          0 :     if (result != NULL) {
     382                 :          0 :         return result;
     383                 :            :     }
     384         [ #  # ]:          0 :     if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) {
     385                 :          0 :         _PyGen_SetStopIterationValue(obj->default_value);
     386                 :            :     }
     387                 :          0 :     return NULL;
     388                 :            : }
     389                 :            : 
     390                 :            : 
     391                 :            : static PyObject *
     392                 :          0 : anextawaitable_proxy(anextawaitableobject *obj, char *meth, PyObject *arg) {
     393                 :          0 :     PyObject *awaitable = anextawaitable_getiter(obj);
     394         [ #  # ]:          0 :     if (awaitable == NULL) {
     395                 :          0 :         return NULL;
     396                 :            :     }
     397                 :          0 :     PyObject *ret = PyObject_CallMethod(awaitable, meth, "O", arg);
     398                 :          0 :     Py_DECREF(awaitable);
     399         [ #  # ]:          0 :     if (ret != NULL) {
     400                 :          0 :         return ret;
     401                 :            :     }
     402         [ #  # ]:          0 :     if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) {
     403                 :            :         /* `anextawaitableobject` is only used by `anext()` when
     404                 :            :          * a default value is provided. So when we have a StopAsyncIteration
     405                 :            :          * exception we replace it with a `StopIteration(default)`, as if
     406                 :            :          * it was the return value of `__anext__()` coroutine.
     407                 :            :          */
     408                 :          0 :         _PyGen_SetStopIterationValue(obj->default_value);
     409                 :            :     }
     410                 :          0 :     return NULL;
     411                 :            : }
     412                 :            : 
     413                 :            : 
     414                 :            : static PyObject *
     415                 :          0 : anextawaitable_send(anextawaitableobject *obj, PyObject *arg) {
     416                 :          0 :     return anextawaitable_proxy(obj, "send", arg);
     417                 :            : }
     418                 :            : 
     419                 :            : 
     420                 :            : static PyObject *
     421                 :          0 : anextawaitable_throw(anextawaitableobject *obj, PyObject *arg) {
     422                 :          0 :     return anextawaitable_proxy(obj, "throw", arg);
     423                 :            : }
     424                 :            : 
     425                 :            : 
     426                 :            : static PyObject *
     427                 :          0 : anextawaitable_close(anextawaitableobject *obj, PyObject *arg) {
     428                 :          0 :     return anextawaitable_proxy(obj, "close", arg);
     429                 :            : }
     430                 :            : 
     431                 :            : 
     432                 :            : PyDoc_STRVAR(send_doc,
     433                 :            : "send(arg) -> send 'arg' into the wrapped iterator,\n\
     434                 :            : return next yielded value or raise StopIteration.");
     435                 :            : 
     436                 :            : 
     437                 :            : PyDoc_STRVAR(throw_doc,
     438                 :            : "throw(value)\n\
     439                 :            : throw(typ[,val[,tb]])\n\
     440                 :            : \n\
     441                 :            : raise exception in the wrapped iterator, return next yielded value\n\
     442                 :            : or raise StopIteration.\n\
     443                 :            : the (type, val, tb) signature is deprecated, \n\
     444                 :            : and may be removed in a future version of Python.");
     445                 :            : 
     446                 :            : 
     447                 :            : PyDoc_STRVAR(close_doc,
     448                 :            : "close() -> raise GeneratorExit inside generator.");
     449                 :            : 
     450                 :            : 
     451                 :            : static PyMethodDef anextawaitable_methods[] = {
     452                 :            :     {"send",(PyCFunction)anextawaitable_send, METH_O, send_doc},
     453                 :            :     {"throw",(PyCFunction)anextawaitable_throw, METH_VARARGS, throw_doc},
     454                 :            :     {"close",(PyCFunction)anextawaitable_close, METH_VARARGS, close_doc},
     455                 :            :     {NULL, NULL}        /* Sentinel */
     456                 :            : };
     457                 :            : 
     458                 :            : 
     459                 :            : static PyAsyncMethods anextawaitable_as_async = {
     460                 :            :     PyObject_SelfIter,                          /* am_await */
     461                 :            :     0,                                          /* am_aiter */
     462                 :            :     0,                                          /* am_anext */
     463                 :            :     0,                                          /* am_send  */
     464                 :            : };
     465                 :            : 
     466                 :            : PyTypeObject _PyAnextAwaitable_Type = {
     467                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     468                 :            :     "anext_awaitable",                          /* tp_name */
     469                 :            :     sizeof(anextawaitableobject),               /* tp_basicsize */
     470                 :            :     0,                                          /* tp_itemsize */
     471                 :            :     /* methods */
     472                 :            :     (destructor)anextawaitable_dealloc,         /* tp_dealloc */
     473                 :            :     0,                                          /* tp_vectorcall_offset */
     474                 :            :     0,                                          /* tp_getattr */
     475                 :            :     0,                                          /* tp_setattr */
     476                 :            :     &anextawaitable_as_async,                   /* tp_as_async */
     477                 :            :     0,                                          /* tp_repr */
     478                 :            :     0,                                          /* tp_as_number */
     479                 :            :     0,                                          /* tp_as_sequence */
     480                 :            :     0,                                          /* tp_as_mapping */
     481                 :            :     0,                                          /* tp_hash */
     482                 :            :     0,                                          /* tp_call */
     483                 :            :     0,                                          /* tp_str */
     484                 :            :     PyObject_GenericGetAttr,                    /* tp_getattro */
     485                 :            :     0,                                          /* tp_setattro */
     486                 :            :     0,                                          /* tp_as_buffer */
     487                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
     488                 :            :     0,                                          /* tp_doc */
     489                 :            :     (traverseproc)anextawaitable_traverse,      /* tp_traverse */
     490                 :            :     0,                                          /* tp_clear */
     491                 :            :     0,                                          /* tp_richcompare */
     492                 :            :     0,                                          /* tp_weaklistoffset */
     493                 :            :     PyObject_SelfIter,                          /* tp_iter */
     494                 :            :     (unaryfunc)anextawaitable_iternext,         /* tp_iternext */
     495                 :            :     anextawaitable_methods,                     /* tp_methods */
     496                 :            : };
     497                 :            : 
     498                 :            : PyObject *
     499                 :          0 : PyAnextAwaitable_New(PyObject *awaitable, PyObject *default_value)
     500                 :            : {
     501                 :          0 :     anextawaitableobject *anext = PyObject_GC_New(
     502                 :            :             anextawaitableobject, &_PyAnextAwaitable_Type);
     503         [ #  # ]:          0 :     if (anext == NULL) {
     504                 :          0 :         return NULL;
     505                 :            :     }
     506                 :          0 :     anext->wrapped = Py_NewRef(awaitable);
     507                 :          0 :     anext->default_value = Py_NewRef(default_value);
     508                 :          0 :     _PyObject_GC_TRACK(anext);
     509                 :          0 :     return (PyObject *)anext;
     510                 :            : }

Generated by: LCOV version 1.14