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 next_item
= (*it
->ob_type
->tp_iternext
)(it
);
66 if (next_item
== NULL
)
69 next_index
= PyInt_FromLong(en
->en_index
);
70 if (next_index
== NULL
) {
76 if (result
->ob_refcnt
== 1) {
78 Py_DECREF(PyTuple_GET_ITEM(result
, 0));
79 Py_DECREF(PyTuple_GET_ITEM(result
, 1));
81 result
= PyTuple_New(2);
83 Py_DECREF(next_index
);
88 PyTuple_SET_ITEM(result
, 0, next_index
);
89 PyTuple_SET_ITEM(result
, 1, next_item
);
93 PyDoc_STRVAR(enum_doc
,
94 "enumerate(iterable) -> iterator for index, value of iterable\n"
96 "Return an enumerate object. iterable must be an other object that supports\n"
97 "iteration. The enumerate object yields pairs containing a count (from\n"
98 "zero) and a value yielded by the iterable argument. enumerate is useful\n"
99 "for obtaining an indexed list: (0, seq[0]), (1, seq[1]), (2, seq[2]), ...");
101 PyTypeObject PyEnum_Type
= {
102 PyObject_HEAD_INIT(&PyType_Type
)
104 "enumerate", /* tp_name */
105 sizeof(enumobject
), /* tp_basicsize */
108 (destructor
)enum_dealloc
, /* tp_dealloc */
114 0, /* tp_as_number */
115 0, /* tp_as_sequence */
116 0, /* tp_as_mapping */
120 PyObject_GenericGetAttr
, /* tp_getattro */
122 0, /* tp_as_buffer */
123 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
124 Py_TPFLAGS_BASETYPE
, /* tp_flags */
125 enum_doc
, /* tp_doc */
126 (traverseproc
)enum_traverse
, /* tp_traverse */
128 0, /* tp_richcompare */
129 0, /* tp_weaklistoffset */
130 PyObject_SelfIter
, /* tp_iter */
131 (iternextfunc
)enum_next
, /* tp_iternext */
137 0, /* tp_descr_get */
138 0, /* tp_descr_set */
139 0, /* tp_dictoffset */
141 PyType_GenericAlloc
, /* tp_alloc */
142 enum_new
, /* tp_new */
143 PyObject_GC_Del
, /* tp_free */
146 /* Reversed Object ***************************************************************/
155 reversed_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
161 if (!PyArg_UnpackTuple(args
, "reversed", 1, 1, &seq
))
164 if (PyObject_HasAttrString(seq
, "__reversed__"))
165 return PyObject_CallMethod(seq
, "__reversed__", NULL
);
167 if (!PySequence_Check(seq
)) {
168 PyErr_SetString(PyExc_TypeError
,
169 "argument to reversed() must be a sequence");
173 n
= PySequence_Size(seq
);
177 ro
= (reversedobject
*)type
->tp_alloc(type
, 0);
184 return (PyObject
*)ro
;
188 reversed_dealloc(reversedobject
*ro
)
190 PyObject_GC_UnTrack(ro
);
192 ro
->ob_type
->tp_free(ro
);
196 reversed_traverse(reversedobject
*ro
, visitproc visit
, void *arg
)
203 reversed_next(reversedobject
*ro
)
206 Py_ssize_t index
= ro
->index
;
209 item
= PySequence_GetItem(ro
->seq
, index
);
214 if (PyErr_ExceptionMatches(PyExc_IndexError
) ||
215 PyErr_ExceptionMatches(PyExc_StopIteration
))
223 PyDoc_STRVAR(reversed_doc
,
224 "reversed(sequence) -> reverse iterator over values of the sequence\n"
226 "Return a reverse iterator");
229 reversed_len(reversedobject
*ro
)
231 Py_ssize_t position
, seqsize
;
234 return PyInt_FromLong(0);
235 seqsize
= PySequence_Size(ro
->seq
);
238 position
= ro
->index
+ 1;
239 return PyInt_FromSsize_t((seqsize
< position
) ? 0 : position
);
242 PyDoc_STRVAR(length_hint_doc
, "Private method returning an estimate of len(list(it)).");
244 static PyMethodDef reversediter_methods
[] = {
245 {"__length_hint__", (PyCFunction
)reversed_len
, METH_NOARGS
, length_hint_doc
},
246 {NULL
, NULL
} /* sentinel */
249 PyTypeObject PyReversed_Type
= {
250 PyObject_HEAD_INIT(&PyType_Type
)
252 "reversed", /* tp_name */
253 sizeof(reversedobject
), /* tp_basicsize */
256 (destructor
)reversed_dealloc
, /* tp_dealloc */
262 0, /* tp_as_number */
263 0, /* tp_as_sequence */
264 0, /* tp_as_mapping */
268 PyObject_GenericGetAttr
, /* tp_getattro */
270 0, /* tp_as_buffer */
271 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
272 Py_TPFLAGS_BASETYPE
, /* tp_flags */
273 reversed_doc
, /* tp_doc */
274 (traverseproc
)reversed_traverse
,/* tp_traverse */
276 0, /* tp_richcompare */
277 0, /* tp_weaklistoffset */
278 PyObject_SelfIter
, /* tp_iter */
279 (iternextfunc
)reversed_next
, /* tp_iternext */
280 reversediter_methods
, /* tp_methods */
285 0, /* tp_descr_get */
286 0, /* tp_descr_set */
287 0, /* tp_dictoffset */
289 PyType_GenericAlloc
, /* tp_alloc */
290 reversed_new
, /* tp_new */
291 PyObject_GC_Del
, /* tp_free */