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
)
41 if (it
->it_seq
== NULL
)
43 return visit(it
->it_seq
, arg
);
47 iter_iternext(PyObject
*iterator
)
53 assert(PySeqIter_Check(iterator
));
54 it
= (seqiterobject
*)iterator
;
59 result
= PySequence_GetItem(seq
, it
->it_index
);
64 if (PyErr_ExceptionMatches(PyExc_IndexError
) ||
65 PyErr_ExceptionMatches(PyExc_StopIteration
))
75 iter_len(seqiterobject
*it
)
80 seqsize
= PySequence_Size(it
->it_seq
);
83 len
= seqsize
- it
->it_index
;
85 return PyInt_FromLong(len
);
87 return PyInt_FromLong(0);
90 PyDoc_STRVAR(length_cue_doc
, "Private method returning an estimate of len(list(it)).");
92 static PyMethodDef seqiter_methods
[] = {
93 {"_length_cue", (PyCFunction
)iter_len
, METH_NOARGS
, length_cue_doc
},
94 {NULL
, NULL
} /* sentinel */
97 PyTypeObject PySeqIter_Type
= {
98 PyObject_HEAD_INIT(&PyType_Type
)
100 "iterator", /* tp_name */
101 sizeof(seqiterobject
), /* tp_basicsize */
104 (destructor
)iter_dealloc
, /* tp_dealloc */
110 0, /* tp_as_number */
111 0, /* tp_as_sequence */
112 0, /* tp_as_mapping */
116 PyObject_GenericGetAttr
, /* tp_getattro */
118 0, /* tp_as_buffer */
119 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
,/* tp_flags */
121 (traverseproc
)iter_traverse
, /* tp_traverse */
123 0, /* tp_richcompare */
124 0, /* tp_weaklistoffset */
125 PyObject_SelfIter
, /* tp_iter */
126 (iternextfunc
)iter_iternext
, /* tp_iternext */
127 seqiter_methods
, /* tp_methods */
131 /* -------------------------------------- */
135 PyObject
*it_callable
; /* Set to NULL when iterator is exhausted */
136 PyObject
*it_sentinel
; /* Set to NULL when iterator is exhausted */
140 PyCallIter_New(PyObject
*callable
, PyObject
*sentinel
)
143 it
= PyObject_GC_New(calliterobject
, &PyCallIter_Type
);
147 it
->it_callable
= callable
;
149 it
->it_sentinel
= sentinel
;
150 _PyObject_GC_TRACK(it
);
151 return (PyObject
*)it
;
154 calliter_dealloc(calliterobject
*it
)
156 _PyObject_GC_UNTRACK(it
);
157 Py_XDECREF(it
->it_callable
);
158 Py_XDECREF(it
->it_sentinel
);
163 calliter_traverse(calliterobject
*it
, visitproc visit
, void *arg
)
166 if (it
->it_callable
!= NULL
&& (err
= visit(it
->it_callable
, arg
)))
168 if (it
->it_sentinel
!= NULL
&& (err
= visit(it
->it_sentinel
, arg
)))
174 calliter_iternext(calliterobject
*it
)
176 if (it
->it_callable
!= NULL
) {
177 PyObject
*args
= PyTuple_New(0);
181 result
= PyObject_Call(it
->it_callable
, args
, NULL
);
183 if (result
!= NULL
) {
185 ok
= PyObject_RichCompareBool(result
,
189 return result
; /* Common case, fast path */
192 Py_CLEAR(it
->it_callable
);
193 Py_CLEAR(it
->it_sentinel
);
196 else if (PyErr_ExceptionMatches(PyExc_StopIteration
)) {
198 Py_CLEAR(it
->it_callable
);
199 Py_CLEAR(it
->it_sentinel
);
205 PyTypeObject PyCallIter_Type
= {
206 PyObject_HEAD_INIT(&PyType_Type
)
208 "callable-iterator", /* tp_name */
209 sizeof(calliterobject
), /* tp_basicsize */
212 (destructor
)calliter_dealloc
, /* tp_dealloc */
218 0, /* tp_as_number */
219 0, /* tp_as_sequence */
220 0, /* tp_as_mapping */
224 PyObject_GenericGetAttr
, /* tp_getattro */
226 0, /* tp_as_buffer */
227 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
,/* tp_flags */
229 (traverseproc
)calliter_traverse
, /* tp_traverse */
231 0, /* tp_richcompare */
232 0, /* tp_weaklistoffset */
233 PyObject_SelfIter
, /* tp_iter */
234 (iternextfunc
)calliter_iternext
, /* tp_iternext */