8 PyObject
*it_seq
; /* Set to NULL when iterator is exhausted */
12 PySeqIter_New(PyObject
*seq
)
16 if (!PySequence_Check(seq
)) {
17 PyErr_BadInternalCall();
20 it
= PyObject_GC_New(seqiterobject
, &PySeqIter_Type
);
26 _PyObject_GC_TRACK(it
);
27 return (PyObject
*)it
;
31 iter_dealloc(seqiterobject
*it
)
33 _PyObject_GC_UNTRACK(it
);
34 Py_XDECREF(it
->it_seq
);
39 iter_traverse(seqiterobject
*it
, visitproc visit
, void *arg
)
46 iter_iternext(PyObject
*iterator
)
52 assert(PySeqIter_Check(iterator
));
53 it
= (seqiterobject
*)iterator
;
58 result
= PySequence_GetItem(seq
, it
->it_index
);
63 if (PyErr_ExceptionMatches(PyExc_IndexError
) ||
64 PyErr_ExceptionMatches(PyExc_StopIteration
))
74 iter_len(seqiterobject
*it
)
76 Py_ssize_t seqsize
, len
;
79 seqsize
= PySequence_Size(it
->it_seq
);
82 len
= seqsize
- it
->it_index
;
84 return PyInt_FromSsize_t(len
);
86 return PyInt_FromLong(0);
89 PyDoc_STRVAR(length_hint_doc
, "Private method returning an estimate of len(list(it)).");
91 static PyMethodDef seqiter_methods
[] = {
92 {"__length_hint__", (PyCFunction
)iter_len
, METH_NOARGS
, length_hint_doc
},
93 {NULL
, NULL
} /* sentinel */
96 PyTypeObject PySeqIter_Type
= {
97 PyObject_HEAD_INIT(&PyType_Type
)
99 "iterator", /* tp_name */
100 sizeof(seqiterobject
), /* tp_basicsize */
103 (destructor
)iter_dealloc
, /* tp_dealloc */
109 0, /* tp_as_number */
110 0, /* tp_as_sequence */
111 0, /* tp_as_mapping */
115 PyObject_GenericGetAttr
, /* tp_getattro */
117 0, /* tp_as_buffer */
118 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
,/* tp_flags */
120 (traverseproc
)iter_traverse
, /* tp_traverse */
122 0, /* tp_richcompare */
123 0, /* tp_weaklistoffset */
124 PyObject_SelfIter
, /* tp_iter */
125 iter_iternext
, /* tp_iternext */
126 seqiter_methods
, /* tp_methods */
130 /* -------------------------------------- */
134 PyObject
*it_callable
; /* Set to NULL when iterator is exhausted */
135 PyObject
*it_sentinel
; /* Set to NULL when iterator is exhausted */
139 PyCallIter_New(PyObject
*callable
, PyObject
*sentinel
)
142 it
= PyObject_GC_New(calliterobject
, &PyCallIter_Type
);
146 it
->it_callable
= callable
;
148 it
->it_sentinel
= sentinel
;
149 _PyObject_GC_TRACK(it
);
150 return (PyObject
*)it
;
153 calliter_dealloc(calliterobject
*it
)
155 _PyObject_GC_UNTRACK(it
);
156 Py_XDECREF(it
->it_callable
);
157 Py_XDECREF(it
->it_sentinel
);
162 calliter_traverse(calliterobject
*it
, visitproc visit
, void *arg
)
164 Py_VISIT(it
->it_callable
);
165 Py_VISIT(it
->it_sentinel
);
170 calliter_iternext(calliterobject
*it
)
172 if (it
->it_callable
!= NULL
) {
173 PyObject
*args
= PyTuple_New(0);
177 result
= PyObject_Call(it
->it_callable
, args
, NULL
);
179 if (result
!= NULL
) {
181 ok
= PyObject_RichCompareBool(result
,
185 return result
; /* Common case, fast path */
188 Py_CLEAR(it
->it_callable
);
189 Py_CLEAR(it
->it_sentinel
);
192 else if (PyErr_ExceptionMatches(PyExc_StopIteration
)) {
194 Py_CLEAR(it
->it_callable
);
195 Py_CLEAR(it
->it_sentinel
);
201 PyTypeObject PyCallIter_Type
= {
202 PyObject_HEAD_INIT(&PyType_Type
)
204 "callable-iterator", /* tp_name */
205 sizeof(calliterobject
), /* tp_basicsize */
208 (destructor
)calliter_dealloc
, /* tp_dealloc */
214 0, /* tp_as_number */
215 0, /* tp_as_sequence */
216 0, /* tp_as_mapping */
220 PyObject_GenericGetAttr
, /* tp_getattro */
222 0, /* tp_as_buffer */
223 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
,/* tp_flags */
225 (traverseproc
)calliter_traverse
, /* tp_traverse */
227 0, /* tp_richcompare */
228 0, /* tp_weaklistoffset */
229 PyObject_SelfIter
, /* tp_iter */
230 (iternextfunc
)calliter_iternext
, /* tp_iternext */