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 PyVarObject_HEAD_INIT(&PyType_Type
, 0)
98 "iterator", /* tp_name */
99 sizeof(seqiterobject
), /* tp_basicsize */
102 (destructor
)iter_dealloc
, /* tp_dealloc */
108 0, /* tp_as_number */
109 0, /* tp_as_sequence */
110 0, /* tp_as_mapping */
114 PyObject_GenericGetAttr
, /* tp_getattro */
116 0, /* tp_as_buffer */
117 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
,/* tp_flags */
119 (traverseproc
)iter_traverse
, /* tp_traverse */
121 0, /* tp_richcompare */
122 0, /* tp_weaklistoffset */
123 PyObject_SelfIter
, /* tp_iter */
124 iter_iternext
, /* tp_iternext */
125 seqiter_methods
, /* tp_methods */
129 /* -------------------------------------- */
133 PyObject
*it_callable
; /* Set to NULL when iterator is exhausted */
134 PyObject
*it_sentinel
; /* Set to NULL when iterator is exhausted */
138 PyCallIter_New(PyObject
*callable
, PyObject
*sentinel
)
141 it
= PyObject_GC_New(calliterobject
, &PyCallIter_Type
);
145 it
->it_callable
= callable
;
147 it
->it_sentinel
= sentinel
;
148 _PyObject_GC_TRACK(it
);
149 return (PyObject
*)it
;
152 calliter_dealloc(calliterobject
*it
)
154 _PyObject_GC_UNTRACK(it
);
155 Py_XDECREF(it
->it_callable
);
156 Py_XDECREF(it
->it_sentinel
);
161 calliter_traverse(calliterobject
*it
, visitproc visit
, void *arg
)
163 Py_VISIT(it
->it_callable
);
164 Py_VISIT(it
->it_sentinel
);
169 calliter_iternext(calliterobject
*it
)
171 if (it
->it_callable
!= NULL
) {
172 PyObject
*args
= PyTuple_New(0);
176 result
= PyObject_Call(it
->it_callable
, args
, NULL
);
178 if (result
!= NULL
) {
180 ok
= PyObject_RichCompareBool(result
,
184 return result
; /* Common case, fast path */
187 Py_CLEAR(it
->it_callable
);
188 Py_CLEAR(it
->it_sentinel
);
191 else if (PyErr_ExceptionMatches(PyExc_StopIteration
)) {
193 Py_CLEAR(it
->it_callable
);
194 Py_CLEAR(it
->it_sentinel
);
200 PyTypeObject PyCallIter_Type
= {
201 PyVarObject_HEAD_INIT(&PyType_Type
, 0)
202 "callable-iterator", /* tp_name */
203 sizeof(calliterobject
), /* tp_basicsize */
206 (destructor
)calliter_dealloc
, /* tp_dealloc */
212 0, /* tp_as_number */
213 0, /* tp_as_sequence */
214 0, /* tp_as_mapping */
218 PyObject_GenericGetAttr
, /* tp_getattro */
220 0, /* tp_as_buffer */
221 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
,/* tp_flags */
223 (traverseproc
)calliter_traverse
, /* tp_traverse */
225 0, /* tp_richcompare */
226 0, /* tp_weaklistoffset */
227 PyObject_SelfIter
, /* tp_iter */
228 (iternextfunc
)calliter_iternext
, /* tp_iternext */