LCOV - code coverage report
Current view: | top level - Objects - enumobject.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 99 | 223 | 44.4 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 9 | 16 | 56.2 %
|  |  | Branches: | 40 | 136 | 29.4 %

               Branch data     Line data    Source code
           1                 :            : /* enumerate object */
           2                 :            :
           3                 :            : #include "Python.h"
           4                 :            : #include "pycore_call.h"          // _PyObject_CallNoArgs()
           5                 :            : #include "pycore_long.h"          // _PyLong_GetOne()
           6                 :            : #include "pycore_object.h"        // _PyObject_GC_TRACK()
           7                 :            :
           8                 :            : #include "clinic/enumobject.c.h"
           9                 :            :
          10                 :            : /*[clinic input]
          11                 :            : class enumerate "enumobject *" "&PyEnum_Type"
          12                 :            : class reversed "reversedobject *" "&PyReversed_Type"
          13                 :            : [clinic start generated code]*/
          14                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=d2dfdf1a88c88975]*/
          15                 :            :
          16                 :            : typedef struct {
          17                 :            :     PyObject_HEAD
          18                 :            :     Py_ssize_t en_index;           /* current index of enumeration */
          19                 :            :     PyObject* en_sit;              /* secondary iterator of enumeration */
          20                 :            :     PyObject* en_result;           /* result tuple  */
          21                 :            :     PyObject* en_longindex;        /* index for sequences >= PY_SSIZE_T_MAX */
          22                 :            :     PyObject* one;                 /* borrowed reference */
          23                 :            : } enumobject;
          24                 :            :
          25                 :            :
          26                 :            : /*[clinic input]
          27                 :            : @classmethod
          28                 :            : enumerate.__new__ as enum_new
          29                 :            :
          30                 :            :     iterable: object
          31                 :            :         an object supporting iteration
          32                 :            :     start: object = 0
          33                 :            :
          34                 :            : Return an enumerate object.
          35                 :            :
          36                 :            : The enumerate object yields pairs containing a count (from start, which
          37                 :            : defaults to zero) and a value yielded by the iterable argument.
          38                 :            :
          39                 :            : enumerate is useful for obtaining an indexed list:
          40                 :            :     (0, seq[0]), (1, seq[1]), (2, seq[2]), ...
          41                 :            : [clinic start generated code]*/
          42                 :            :
          43                 :            : static PyObject *
          44                 :       3479 : enum_new_impl(PyTypeObject *type, PyObject *iterable, PyObject *start)
          45                 :            : /*[clinic end generated code: output=e95e6e439f812c10 input=782e4911efcb8acf]*/
          46                 :            : {
          47                 :            :     enumobject *en;
          48                 :            :
          49                 :       3479 :     en = (enumobject *)type->tp_alloc(type, 0);
          50         [ -  + ]:       3479 :     if (en == NULL)
          51                 :          0 :         return NULL;
          52         [ +  + ]:       3479 :     if (start != NULL) {
          53                 :        624 :         start = PyNumber_Index(start);
          54         [ -  + ]:        624 :         if (start == NULL) {
          55                 :          0 :             Py_DECREF(en);
          56                 :          0 :             return NULL;
          57                 :            :         }
          58                 :            :         assert(PyLong_Check(start));
          59                 :        624 :         en->en_index = PyLong_AsSsize_t(start);
          60   [ -  +  -  - ]:        624 :         if (en->en_index == -1 && PyErr_Occurred()) {
          61                 :          0 :             PyErr_Clear();
          62                 :          0 :             en->en_index = PY_SSIZE_T_MAX;
          63                 :          0 :             en->en_longindex = start;
          64                 :            :         } else {
          65                 :        624 :             en->en_longindex = NULL;
          66                 :        624 :             Py_DECREF(start);
          67                 :            :         }
          68                 :            :     } else {
          69                 :       2855 :         en->en_index = 0;
          70                 :       2855 :         en->en_longindex = NULL;
          71                 :            :     }
          72                 :       3479 :     en->en_sit = PyObject_GetIter(iterable);
          73         [ -  + ]:       3479 :     if (en->en_sit == NULL) {
          74                 :          0 :         Py_DECREF(en);
          75                 :          0 :         return NULL;
          76                 :            :     }
          77                 :       3479 :     en->en_result = PyTuple_Pack(2, Py_None, Py_None);
          78         [ -  + ]:       3479 :     if (en->en_result == NULL) {
          79                 :          0 :         Py_DECREF(en);
          80                 :          0 :         return NULL;
          81                 :            :     }
          82                 :       3479 :     en->one = _PyLong_GetOne();    /* borrowed reference */
          83                 :       3479 :     return (PyObject *)en;
          84                 :            : }
          85                 :            :
          86                 :          0 : static int check_keyword(PyObject *kwnames, int index,
          87                 :            :                          const char *name)
          88                 :            : {
          89                 :          0 :     PyObject *kw = PyTuple_GET_ITEM(kwnames, index);
          90         [ #  # ]:          0 :     if (!_PyUnicode_EqualToASCIIString(kw, name)) {
          91                 :          0 :         PyErr_Format(PyExc_TypeError,
          92                 :            :             "'%S' is an invalid keyword argument for enumerate()", kw);
          93                 :          0 :         return 0;
          94                 :            :     }
          95                 :          0 :     return 1;
          96                 :            : }
          97                 :            :
          98                 :            : // TODO: Use AC when bpo-43447 is supported
          99                 :            : static PyObject *
         100                 :       3479 : enumerate_vectorcall(PyObject *type, PyObject *const *args,
         101                 :            :                      size_t nargsf, PyObject *kwnames)
         102                 :            : {
         103                 :       3479 :     PyTypeObject *tp = _PyType_CAST(type);
         104                 :       3479 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
         105                 :       3479 :     Py_ssize_t nkwargs = 0;
         106         [ -  + ]:       3479 :     if (kwnames != NULL) {
         107                 :          0 :         nkwargs = PyTuple_GET_SIZE(kwnames);
         108                 :            :     }
         109                 :            :
         110                 :            :     // Manually implement enumerate(iterable, start=...)
         111         [ +  + ]:       3479 :     if (nargs + nkwargs == 2) {
         112         [ -  + ]:        624 :         if (nkwargs == 1) {
         113         [ #  # ]:          0 :             if (!check_keyword(kwnames, 0, "start")) {
         114                 :          0 :                 return NULL;
         115                 :            :             }
         116         [ -  + ]:        624 :         } else if (nkwargs == 2) {
         117                 :          0 :             PyObject *kw0 = PyTuple_GET_ITEM(kwnames, 0);
         118         [ #  # ]:          0 :             if (_PyUnicode_EqualToASCIIString(kw0, "start")) {
         119         [ #  # ]:          0 :                 if (!check_keyword(kwnames, 1, "iterable")) {
         120                 :          0 :                     return NULL;
         121                 :            :                 }
         122                 :          0 :                 return enum_new_impl(tp, args[1], args[0]);
         123                 :            :             }
         124   [ #  #  #  # ]:          0 :             if (!check_keyword(kwnames, 0, "iterable") ||
         125                 :          0 :                 !check_keyword(kwnames, 1, "start")) {
         126                 :          0 :                 return NULL;
         127                 :            :             }
         128                 :            :
         129                 :            :         }
         130                 :        624 :         return enum_new_impl(tp, args[0], args[1]);
         131                 :            :     }
         132                 :            :
         133         [ +  - ]:       2855 :     if (nargs + nkwargs == 1) {
         134   [ -  +  -  - ]:       2855 :         if (nkwargs == 1 && !check_keyword(kwnames, 0, "iterable")) {
         135                 :          0 :             return NULL;
         136                 :            :         }
         137                 :       2855 :         return enum_new_impl(tp, args[0], NULL);
         138                 :            :     }
         139                 :            :
         140         [ #  # ]:          0 :     if (nargs == 0) {
         141                 :          0 :         PyErr_SetString(PyExc_TypeError,
         142                 :            :             "enumerate() missing required argument 'iterable'");
         143                 :          0 :         return NULL;
         144                 :            :     }
         145                 :            :
         146                 :          0 :     PyErr_Format(PyExc_TypeError,
         147                 :            :         "enumerate() takes at most 2 arguments (%d given)", nargs + nkwargs);
         148                 :          0 :     return NULL;
         149                 :            : }
         150                 :            :
         151                 :            : static void
         152                 :       3479 : enum_dealloc(enumobject *en)
         153                 :            : {
         154                 :       3479 :     PyObject_GC_UnTrack(en);
         155                 :       3479 :     Py_XDECREF(en->en_sit);
         156                 :       3479 :     Py_XDECREF(en->en_result);
         157                 :       3479 :     Py_XDECREF(en->en_longindex);
         158                 :       3479 :     Py_TYPE(en)->tp_free(en);
         159                 :       3479 : }
         160                 :            :
         161                 :            : static int
         162                 :         56 : enum_traverse(enumobject *en, visitproc visit, void *arg)
         163                 :            : {
         164   [ +  -  -  + ]:         56 :     Py_VISIT(en->en_sit);
         165   [ +  -  -  + ]:         56 :     Py_VISIT(en->en_result);
         166   [ -  +  -  - ]:         56 :     Py_VISIT(en->en_longindex);
         167                 :         56 :     return 0;
         168                 :            : }
         169                 :            :
         170                 :            : static PyObject *
         171                 :          0 : enum_next_long(enumobject *en, PyObject* next_item)
         172                 :            : {
         173                 :          0 :     PyObject *result = en->en_result;
         174                 :            :     PyObject *next_index;
         175                 :            :     PyObject *stepped_up;
         176                 :            :     PyObject *old_index;
         177                 :            :     PyObject *old_item;
         178                 :            :
         179         [ #  # ]:          0 :     if (en->en_longindex == NULL) {
         180                 :          0 :         en->en_longindex = PyLong_FromSsize_t(PY_SSIZE_T_MAX);
         181         [ #  # ]:          0 :         if (en->en_longindex == NULL) {
         182                 :          0 :             Py_DECREF(next_item);
         183                 :          0 :             return NULL;
         184                 :            :         }
         185                 :            :     }
         186                 :          0 :     next_index = en->en_longindex;
         187                 :            :     assert(next_index != NULL);
         188                 :          0 :     stepped_up = PyNumber_Add(next_index, en->one);
         189         [ #  # ]:          0 :     if (stepped_up == NULL) {
         190                 :          0 :         Py_DECREF(next_item);
         191                 :          0 :         return NULL;
         192                 :            :     }
         193                 :          0 :     en->en_longindex = stepped_up;
         194                 :            :
         195         [ #  # ]:          0 :     if (Py_REFCNT(result) == 1) {
         196                 :          0 :         Py_INCREF(result);
         197                 :          0 :         old_index = PyTuple_GET_ITEM(result, 0);
         198                 :          0 :         old_item = PyTuple_GET_ITEM(result, 1);
         199                 :          0 :         PyTuple_SET_ITEM(result, 0, next_index);
         200                 :          0 :         PyTuple_SET_ITEM(result, 1, next_item);
         201                 :          0 :         Py_DECREF(old_index);
         202                 :          0 :         Py_DECREF(old_item);
         203                 :            :         // bpo-42536: The GC may have untracked this result tuple. Since we're
         204                 :            :         // recycling it, make sure it's tracked again:
         205         [ #  # ]:          0 :         if (!_PyObject_GC_IS_TRACKED(result)) {
         206                 :          0 :             _PyObject_GC_TRACK(result);
         207                 :            :         }
         208                 :          0 :         return result;
         209                 :            :     }
         210                 :          0 :     result = PyTuple_New(2);
         211         [ #  # ]:          0 :     if (result == NULL) {
         212                 :          0 :         Py_DECREF(next_index);
         213                 :          0 :         Py_DECREF(next_item);
         214                 :          0 :         return NULL;
         215                 :            :     }
         216                 :          0 :     PyTuple_SET_ITEM(result, 0, next_index);
         217                 :          0 :     PyTuple_SET_ITEM(result, 1, next_item);
         218                 :          0 :     return result;
         219                 :            : }
         220                 :            :
         221                 :            : static PyObject *
         222                 :     738915 : enum_next(enumobject *en)
         223                 :            : {
         224                 :            :     PyObject *next_index;
         225                 :            :     PyObject *next_item;
         226                 :     738915 :     PyObject *result = en->en_result;
         227                 :     738915 :     PyObject *it = en->en_sit;
         228                 :            :     PyObject *old_index;
         229                 :            :     PyObject *old_item;
         230                 :            :
         231                 :     738915 :     next_item = (*Py_TYPE(it)->tp_iternext)(it);
         232         [ +  + ]:     738915 :     if (next_item == NULL)
         233                 :       2707 :         return NULL;
         234                 :            :
         235         [ -  + ]:     736208 :     if (en->en_index == PY_SSIZE_T_MAX)
         236                 :          0 :         return enum_next_long(en, next_item);
         237                 :            :
         238                 :     736208 :     next_index = PyLong_FromSsize_t(en->en_index);
         239         [ -  + ]:     736208 :     if (next_index == NULL) {
         240                 :          0 :         Py_DECREF(next_item);
         241                 :          0 :         return NULL;
         242                 :            :     }
         243                 :     736208 :     en->en_index++;
         244                 :            :
         245         [ +  - ]:     736208 :     if (Py_REFCNT(result) == 1) {
         246                 :     736208 :         Py_INCREF(result);
         247                 :     736208 :         old_index = PyTuple_GET_ITEM(result, 0);
         248                 :     736208 :         old_item = PyTuple_GET_ITEM(result, 1);
         249                 :     736208 :         PyTuple_SET_ITEM(result, 0, next_index);
         250                 :     736208 :         PyTuple_SET_ITEM(result, 1, next_item);
         251                 :     736208 :         Py_DECREF(old_index);
         252                 :     736208 :         Py_DECREF(old_item);
         253                 :            :         // bpo-42536: The GC may have untracked this result tuple. Since we're
         254                 :            :         // recycling it, make sure it's tracked again:
         255         [ +  + ]:     736208 :         if (!_PyObject_GC_IS_TRACKED(result)) {
         256                 :          5 :             _PyObject_GC_TRACK(result);
         257                 :            :         }
         258                 :     736208 :         return result;
         259                 :            :     }
         260                 :          0 :     result = PyTuple_New(2);
         261         [ #  # ]:          0 :     if (result == NULL) {
         262                 :          0 :         Py_DECREF(next_index);
         263                 :          0 :         Py_DECREF(next_item);
         264                 :          0 :         return NULL;
         265                 :            :     }
         266                 :          0 :     PyTuple_SET_ITEM(result, 0, next_index);
         267                 :          0 :     PyTuple_SET_ITEM(result, 1, next_item);
         268                 :          0 :     return result;
         269                 :            : }
         270                 :            :
         271                 :            : static PyObject *
         272                 :          0 : enum_reduce(enumobject *en, PyObject *Py_UNUSED(ignored))
         273                 :            : {
         274         [ #  # ]:          0 :     if (en->en_longindex != NULL)
         275                 :          0 :         return Py_BuildValue("O(OO)", Py_TYPE(en), en->en_sit, en->en_longindex);
         276                 :            :     else
         277                 :          0 :         return Py_BuildValue("O(On)", Py_TYPE(en), en->en_sit, en->en_index);
         278                 :            : }
         279                 :            :
         280                 :            : PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
         281                 :            :
         282                 :            : static PyMethodDef enum_methods[] = {
         283                 :            :     {"__reduce__", (PyCFunction)enum_reduce, METH_NOARGS, reduce_doc},
         284                 :            :     {"__class_getitem__",    Py_GenericAlias,
         285                 :            :     METH_O|METH_CLASS,       PyDoc_STR("See PEP 585")},
         286                 :            :     {NULL,              NULL}           /* sentinel */
         287                 :            : };
         288                 :            :
         289                 :            : PyTypeObject PyEnum_Type = {
         290                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
         291                 :            :     "enumerate",                    /* tp_name */
         292                 :            :     sizeof(enumobject),             /* tp_basicsize */
         293                 :            :     0,                              /* tp_itemsize */
         294                 :            :     /* methods */
         295                 :            :     (destructor)enum_dealloc,       /* tp_dealloc */
         296                 :            :     0,                              /* tp_vectorcall_offset */
         297                 :            :     0,                              /* tp_getattr */
         298                 :            :     0,                              /* tp_setattr */
         299                 :            :     0,                              /* tp_as_async */
         300                 :            :     0,                              /* tp_repr */
         301                 :            :     0,                              /* tp_as_number */
         302                 :            :     0,                              /* tp_as_sequence */
         303                 :            :     0,                              /* tp_as_mapping */
         304                 :            :     0,                              /* tp_hash */
         305                 :            :     0,                              /* tp_call */
         306                 :            :     0,                              /* tp_str */
         307                 :            :     PyObject_GenericGetAttr,        /* tp_getattro */
         308                 :            :     0,                              /* tp_setattro */
         309                 :            :     0,                              /* tp_as_buffer */
         310                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
         311                 :            :         Py_TPFLAGS_BASETYPE,        /* tp_flags */
         312                 :            :     enum_new__doc__,                /* tp_doc */
         313                 :            :     (traverseproc)enum_traverse,    /* tp_traverse */
         314                 :            :     0,                              /* tp_clear */
         315                 :            :     0,                              /* tp_richcompare */
         316                 :            :     0,                              /* tp_weaklistoffset */
         317                 :            :     PyObject_SelfIter,              /* tp_iter */
         318                 :            :     (iternextfunc)enum_next,        /* tp_iternext */
         319                 :            :     enum_methods,                   /* tp_methods */
         320                 :            :     0,                              /* tp_members */
         321                 :            :     0,                              /* tp_getset */
         322                 :            :     0,                              /* tp_base */
         323                 :            :     0,                              /* tp_dict */
         324                 :            :     0,                              /* tp_descr_get */
         325                 :            :     0,                              /* tp_descr_set */
         326                 :            :     0,                              /* tp_dictoffset */
         327                 :            :     0,                              /* tp_init */
         328                 :            :     PyType_GenericAlloc,            /* tp_alloc */
         329                 :            :     enum_new,                       /* tp_new */
         330                 :            :     PyObject_GC_Del,                /* tp_free */
         331                 :            :     .tp_vectorcall = (vectorcallfunc)enumerate_vectorcall
         332                 :            : };
         333                 :            :
         334                 :            : /* Reversed Object ***************************************************************/
         335                 :            :
         336                 :            : typedef struct {
         337                 :            :     PyObject_HEAD
         338                 :            :     Py_ssize_t      index;
         339                 :            :     PyObject* seq;
         340                 :            : } reversedobject;
         341                 :            :
         342                 :            : /*[clinic input]
         343                 :            : @classmethod
         344                 :            : reversed.__new__ as reversed_new
         345                 :            :
         346                 :            :     sequence as seq: object
         347                 :            :     /
         348                 :            :
         349                 :            : Return a reverse iterator over the values of the given sequence.
         350                 :            : [clinic start generated code]*/
         351                 :            :
         352                 :            : static PyObject *
         353                 :       2275 : reversed_new_impl(PyTypeObject *type, PyObject *seq)
         354                 :            : /*[clinic end generated code: output=f7854cc1df26f570 input=aeb720361e5e3f1d]*/
         355                 :            : {
         356                 :            :     Py_ssize_t n;
         357                 :            :     PyObject *reversed_meth;
         358                 :            :     reversedobject *ro;
         359                 :            :
         360                 :       2275 :     reversed_meth = _PyObject_LookupSpecial(seq, &_Py_ID(__reversed__));
         361         [ -  + ]:       2275 :     if (reversed_meth == Py_None) {
         362                 :          0 :         Py_DECREF(reversed_meth);
         363                 :          0 :         PyErr_Format(PyExc_TypeError,
         364                 :            :                      "'%.200s' object is not reversible",
         365                 :          0 :                      Py_TYPE(seq)->tp_name);
         366                 :          0 :         return NULL;
         367                 :            :     }
         368         [ +  + ]:       2275 :     if (reversed_meth != NULL) {
         369                 :       2267 :         PyObject *res = _PyObject_CallNoArgs(reversed_meth);
         370                 :       2267 :         Py_DECREF(reversed_meth);
         371                 :       2267 :         return res;
         372                 :            :     }
         373         [ -  + ]:          8 :     else if (PyErr_Occurred())
         374                 :          0 :         return NULL;
         375                 :            :
         376         [ -  + ]:          8 :     if (!PySequence_Check(seq)) {
         377                 :          0 :         PyErr_Format(PyExc_TypeError,
         378                 :            :                      "'%.200s' object is not reversible",
         379                 :          0 :                      Py_TYPE(seq)->tp_name);
         380                 :          0 :         return NULL;
         381                 :            :     }
         382                 :            :
         383                 :          8 :     n = PySequence_Size(seq);
         384         [ -  + ]:          8 :     if (n == -1)
         385                 :          0 :         return NULL;
         386                 :            :
         387                 :          8 :     ro = (reversedobject *)type->tp_alloc(type, 0);
         388         [ -  + ]:          8 :     if (ro == NULL)
         389                 :          0 :         return NULL;
         390                 :            :
         391                 :          8 :     ro->index = n-1;
         392                 :          8 :     ro->seq = Py_NewRef(seq);
         393                 :          8 :     return (PyObject *)ro;
         394                 :            : }
         395                 :            :
         396                 :            : static PyObject *
         397                 :       2275 : reversed_vectorcall(PyObject *type, PyObject * const*args,
         398                 :            :                 size_t nargsf, PyObject *kwnames)
         399                 :            : {
         400   [ -  +  -  - ]:       2275 :     if (!_PyArg_NoKwnames("reversed", kwnames)) {
         401                 :          0 :         return NULL;
         402                 :            :     }
         403                 :            :
         404                 :       2275 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
         405   [ +  -  -  +  :       2275 :     if (!_PyArg_CheckPositional("reversed", nargs, 1, 1)) {
                       -  - ]
         406                 :          0 :         return NULL;
         407                 :            :     }
         408                 :            :
         409                 :       2275 :     return reversed_new_impl(_PyType_CAST(type), args[0]);
         410                 :            : }
         411                 :            :
         412                 :            : static void
         413                 :          8 : reversed_dealloc(reversedobject *ro)
         414                 :            : {
         415                 :          8 :     PyObject_GC_UnTrack(ro);
         416                 :          8 :     Py_XDECREF(ro->seq);
         417                 :          8 :     Py_TYPE(ro)->tp_free(ro);
         418                 :          8 : }
         419                 :            :
         420                 :            : static int
         421                 :          0 : reversed_traverse(reversedobject *ro, visitproc visit, void *arg)
         422                 :            : {
         423   [ #  #  #  # ]:          0 :     Py_VISIT(ro->seq);
         424                 :          0 :     return 0;
         425                 :            : }
         426                 :            :
         427                 :            : static PyObject *
         428                 :         24 : reversed_next(reversedobject *ro)
         429                 :            : {
         430                 :            :     PyObject *item;
         431                 :         24 :     Py_ssize_t index = ro->index;
         432                 :            :
         433         [ +  + ]:         24 :     if (index >= 0) {
         434                 :         19 :         item = PySequence_GetItem(ro->seq, index);
         435         [ +  - ]:         19 :         if (item != NULL) {
         436                 :         19 :             ro->index--;
         437                 :         19 :             return item;
         438                 :            :         }
         439   [ #  #  #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_IndexError) ||
         440                 :          0 :             PyErr_ExceptionMatches(PyExc_StopIteration))
         441                 :          0 :             PyErr_Clear();
         442                 :            :     }
         443                 :          5 :     ro->index = -1;
         444         [ +  - ]:          5 :     Py_CLEAR(ro->seq);
         445                 :          5 :     return NULL;
         446                 :            : }
         447                 :            :
         448                 :            : static PyObject *
         449                 :          0 : reversed_len(reversedobject *ro, PyObject *Py_UNUSED(ignored))
         450                 :            : {
         451                 :            :     Py_ssize_t position, seqsize;
         452                 :            :
         453         [ #  # ]:          0 :     if (ro->seq == NULL)
         454                 :          0 :         return PyLong_FromLong(0);
         455                 :          0 :     seqsize = PySequence_Size(ro->seq);
         456         [ #  # ]:          0 :     if (seqsize == -1)
         457                 :          0 :         return NULL;
         458                 :          0 :     position = ro->index + 1;
         459         [ #  # ]:          0 :     return PyLong_FromSsize_t((seqsize < position)  ?  0  :  position);
         460                 :            : }
         461                 :            :
         462                 :            : PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
         463                 :            :
         464                 :            : static PyObject *
         465                 :          0 : reversed_reduce(reversedobject *ro, PyObject *Py_UNUSED(ignored))
         466                 :            : {
         467         [ #  # ]:          0 :     if (ro->seq)
         468                 :          0 :         return Py_BuildValue("O(O)n", Py_TYPE(ro), ro->seq, ro->index);
         469                 :            :     else
         470                 :          0 :         return Py_BuildValue("O(())", Py_TYPE(ro));
         471                 :            : }
         472                 :            :
         473                 :            : static PyObject *
         474                 :          0 : reversed_setstate(reversedobject *ro, PyObject *state)
         475                 :            : {
         476                 :          0 :     Py_ssize_t index = PyLong_AsSsize_t(state);
         477   [ #  #  #  # ]:          0 :     if (index == -1 && PyErr_Occurred())
         478                 :          0 :         return NULL;
         479         [ #  # ]:          0 :     if (ro->seq != 0) {
         480                 :          0 :         Py_ssize_t n = PySequence_Size(ro->seq);
         481         [ #  # ]:          0 :         if (n < 0)
         482                 :          0 :             return NULL;
         483         [ #  # ]:          0 :         if (index < -1)
         484                 :          0 :             index = -1;
         485         [ #  # ]:          0 :         else if (index > n-1)
         486                 :          0 :             index = n-1;
         487                 :          0 :         ro->index = index;
         488                 :            :     }
         489                 :          0 :     Py_RETURN_NONE;
         490                 :            : }
         491                 :            :
         492                 :            : PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
         493                 :            :
         494                 :            : static PyMethodDef reversediter_methods[] = {
         495                 :            :     {"__length_hint__", (PyCFunction)reversed_len, METH_NOARGS, length_hint_doc},
         496                 :            :     {"__reduce__", (PyCFunction)reversed_reduce, METH_NOARGS, reduce_doc},
         497                 :            :     {"__setstate__", (PyCFunction)reversed_setstate, METH_O, setstate_doc},
         498                 :            :     {NULL,              NULL}           /* sentinel */
         499                 :            : };
         500                 :            :
         501                 :            : PyTypeObject PyReversed_Type = {
         502                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
         503                 :            :     "reversed",                     /* tp_name */
         504                 :            :     sizeof(reversedobject),         /* tp_basicsize */
         505                 :            :     0,                              /* tp_itemsize */
         506                 :            :     /* methods */
         507                 :            :     (destructor)reversed_dealloc,   /* tp_dealloc */
         508                 :            :     0,                              /* tp_vectorcall_offset */
         509                 :            :     0,                              /* tp_getattr */
         510                 :            :     0,                              /* tp_setattr */
         511                 :            :     0,                              /* tp_as_async */
         512                 :            :     0,                              /* tp_repr */
         513                 :            :     0,                              /* tp_as_number */
         514                 :            :     0,                              /* tp_as_sequence */
         515                 :            :     0,                              /* tp_as_mapping */
         516                 :            :     0,                              /* tp_hash */
         517                 :            :     0,                              /* tp_call */
         518                 :            :     0,                              /* tp_str */
         519                 :            :     PyObject_GenericGetAttr,        /* tp_getattro */
         520                 :            :     0,                              /* tp_setattro */
         521                 :            :     0,                              /* tp_as_buffer */
         522                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
         523                 :            :         Py_TPFLAGS_BASETYPE,        /* tp_flags */
         524                 :            :     reversed_new__doc__,            /* tp_doc */
         525                 :            :     (traverseproc)reversed_traverse,/* tp_traverse */
         526                 :            :     0,                              /* tp_clear */
         527                 :            :     0,                              /* tp_richcompare */
         528                 :            :     0,                              /* tp_weaklistoffset */
         529                 :            :     PyObject_SelfIter,              /* tp_iter */
         530                 :            :     (iternextfunc)reversed_next,    /* tp_iternext */
         531                 :            :     reversediter_methods,           /* tp_methods */
         532                 :            :     0,                              /* tp_members */
         533                 :            :     0,                              /* tp_getset */
         534                 :            :     0,                              /* tp_base */
         535                 :            :     0,                              /* tp_dict */
         536                 :            :     0,                              /* tp_descr_get */
         537                 :            :     0,                              /* tp_descr_set */
         538                 :            :     0,                              /* tp_dictoffset */
         539                 :            :     0,                              /* tp_init */
         540                 :            :     PyType_GenericAlloc,            /* tp_alloc */
         541                 :            :     reversed_new,                   /* tp_new */
         542                 :            :     PyObject_GC_Del,                /* tp_free */
         543                 :            :     .tp_vectorcall = (vectorcallfunc)reversed_vectorcall,
         544                 :            : };

Generated by: LCOV version 1.14