7 long en_index
; /* current index of enumeration */
8 PyObject
* en_sit
; /* secondary iterator of enumeration */
9 PyObject
* en_result
; /* result tuple */
13 enum_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
17 static char *kwlist
[] = {"sequence", 0};
19 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "O:enumerate", kwlist
,
23 en
= (enumobject
*)type
->tp_alloc(type
, 0);
27 en
->en_sit
= PyObject_GetIter(seq
);
28 if (en
->en_sit
== NULL
) {
32 en
->en_result
= PyTuple_Pack(2, Py_None
, Py_None
);
33 if (en
->en_result
== NULL
) {
37 return (PyObject
*)en
;
41 enum_dealloc(enumobject
*en
)
43 PyObject_GC_UnTrack(en
);
44 Py_XDECREF(en
->en_sit
);
45 Py_XDECREF(en
->en_result
);
46 en
->ob_type
->tp_free(en
);
50 enum_traverse(enumobject
*en
, visitproc visit
, void *arg
)
53 Py_VISIT(en
->en_result
);
58 enum_next(enumobject
*en
)
62 PyObject
*result
= en
->en_result
;
63 PyObject
*it
= en
->en_sit
;
65 if (en
->en_index
== LONG_MAX
) {
66 PyErr_SetString(PyExc_OverflowError
,
67 "enumerate() is limited to LONG_MAX items");
71 next_item
= (*it
->ob_type
->tp_iternext
)(it
);
72 if (next_item
== NULL
)
75 next_index
= PyInt_FromLong(en
->en_index
);
76 if (next_index
== NULL
) {
82 if (result
->ob_refcnt
== 1) {
84 Py_DECREF(PyTuple_GET_ITEM(result
, 0));
85 Py_DECREF(PyTuple_GET_ITEM(result
, 1));
87 result
= PyTuple_New(2);
89 Py_DECREF(next_index
);
94 PyTuple_SET_ITEM(result
, 0, next_index
);
95 PyTuple_SET_ITEM(result
, 1, next_item
);
99 PyDoc_STRVAR(enum_doc
,
100 "enumerate(iterable) -> iterator for index, value of iterable\n"
102 "Return an enumerate object. iterable must be an other object that supports\n"
103 "iteration. The enumerate object yields pairs containing a count (from\n"
104 "zero) and a value yielded by the iterable argument. enumerate is useful\n"
105 "for obtaining an indexed list: (0, seq[0]), (1, seq[1]), (2, seq[2]), ...");
107 PyTypeObject PyEnum_Type
= {
108 PyObject_HEAD_INIT(&PyType_Type
)
110 "enumerate", /* tp_name */
111 sizeof(enumobject
), /* tp_basicsize */
114 (destructor
)enum_dealloc
, /* tp_dealloc */
120 0, /* tp_as_number */
121 0, /* tp_as_sequence */
122 0, /* tp_as_mapping */
126 PyObject_GenericGetAttr
, /* tp_getattro */
128 0, /* tp_as_buffer */
129 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
130 Py_TPFLAGS_BASETYPE
, /* tp_flags */
131 enum_doc
, /* tp_doc */
132 (traverseproc
)enum_traverse
, /* tp_traverse */
134 0, /* tp_richcompare */
135 0, /* tp_weaklistoffset */
136 PyObject_SelfIter
, /* tp_iter */
137 (iternextfunc
)enum_next
, /* tp_iternext */
143 0, /* tp_descr_get */
144 0, /* tp_descr_set */
145 0, /* tp_dictoffset */
147 PyType_GenericAlloc
, /* tp_alloc */
148 enum_new
, /* tp_new */
149 PyObject_GC_Del
, /* tp_free */
152 /* Reversed Object ***************************************************************/
161 reversed_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
167 if (!PyArg_UnpackTuple(args
, "reversed", 1, 1, &seq
))
170 if (PyObject_HasAttrString(seq
, "__reversed__"))
171 return PyObject_CallMethod(seq
, "__reversed__", NULL
);
173 if (!PySequence_Check(seq
)) {
174 PyErr_SetString(PyExc_TypeError
,
175 "argument to reversed() must be a sequence");
179 n
= PySequence_Size(seq
);
183 ro
= (reversedobject
*)type
->tp_alloc(type
, 0);
190 return (PyObject
*)ro
;
194 reversed_dealloc(reversedobject
*ro
)
196 PyObject_GC_UnTrack(ro
);
198 ro
->ob_type
->tp_free(ro
);
202 reversed_traverse(reversedobject
*ro
, visitproc visit
, void *arg
)
209 reversed_next(reversedobject
*ro
)
212 Py_ssize_t index
= ro
->index
;
215 item
= PySequence_GetItem(ro
->seq
, index
);
220 if (PyErr_ExceptionMatches(PyExc_IndexError
) ||
221 PyErr_ExceptionMatches(PyExc_StopIteration
))
229 PyDoc_STRVAR(reversed_doc
,
230 "reversed(sequence) -> reverse iterator over values of the sequence\n"
232 "Return a reverse iterator");
235 reversed_len(reversedobject
*ro
)
237 Py_ssize_t position
, seqsize
;
240 return PyInt_FromLong(0);
241 seqsize
= PySequence_Size(ro
->seq
);
244 position
= ro
->index
+ 1;
245 return PyInt_FromSsize_t((seqsize
< position
) ? 0 : position
);
248 PyDoc_STRVAR(length_hint_doc
, "Private method returning an estimate of len(list(it)).");
250 static PyMethodDef reversediter_methods
[] = {
251 {"__length_hint__", (PyCFunction
)reversed_len
, METH_NOARGS
, length_hint_doc
},
252 {NULL
, NULL
} /* sentinel */
255 PyTypeObject PyReversed_Type
= {
256 PyObject_HEAD_INIT(&PyType_Type
)
258 "reversed", /* tp_name */
259 sizeof(reversedobject
), /* tp_basicsize */
262 (destructor
)reversed_dealloc
, /* tp_dealloc */
268 0, /* tp_as_number */
269 0, /* tp_as_sequence */
270 0, /* tp_as_mapping */
274 PyObject_GenericGetAttr
, /* tp_getattro */
276 0, /* tp_as_buffer */
277 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
278 Py_TPFLAGS_BASETYPE
, /* tp_flags */
279 reversed_doc
, /* tp_doc */
280 (traverseproc
)reversed_traverse
,/* tp_traverse */
282 0, /* tp_richcompare */
283 0, /* tp_weaklistoffset */
284 PyObject_SelfIter
, /* tp_iter */
285 (iternextfunc
)reversed_next
, /* tp_iternext */
286 reversediter_methods
, /* tp_methods */
291 0, /* tp_descr_get */
292 0, /* tp_descr_set */
293 0, /* tp_dictoffset */
295 PyType_GenericAlloc
, /* tp_alloc */
296 reversed_new
, /* tp_new */
297 PyObject_GC_Del
, /* tp_free */