blob: 64bf92382be4bb91d41c6eb6370b391ffd6b20ca [file] [log] [blame]
Guido van Rossum05311482001-04-20 21:06:46 +00001/* Iterator objects */
2
3#include "Python.h"
Victor Stinner621cebe2018-11-12 16:53:38 +01004#include "pycore_pymem.h"
5#include "pycore_pystate.h"
Guido van Rossum05311482001-04-20 21:06:46 +00006
7typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00008 PyObject_HEAD
Victor Stinnere0b99ba2013-06-04 23:02:46 +02009 Py_ssize_t it_index;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000010 PyObject *it_seq; /* Set to NULL when iterator is exhausted */
Guido van Rossum213c7a62001-04-23 14:08:49 +000011} seqiterobject;
Guido van Rossum05311482001-04-20 21:06:46 +000012
13PyObject *
Guido van Rossum213c7a62001-04-23 14:08:49 +000014PySeqIter_New(PyObject *seq)
Guido van Rossum05311482001-04-20 21:06:46 +000015{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000016 seqiterobject *it;
Martin v. Löwis01f94bd2002-05-08 08:44:21 +000017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000018 if (!PySequence_Check(seq)) {
19 PyErr_BadInternalCall();
20 return NULL;
21 }
22 it = PyObject_GC_New(seqiterobject, &PySeqIter_Type);
23 if (it == NULL)
24 return NULL;
25 it->it_index = 0;
26 Py_INCREF(seq);
27 it->it_seq = seq;
28 _PyObject_GC_TRACK(it);
29 return (PyObject *)it;
Guido van Rossum05311482001-04-20 21:06:46 +000030}
Guido van Rossum613bed32002-07-16 20:24:46 +000031
Guido van Rossum05311482001-04-20 21:06:46 +000032static void
Guido van Rossum213c7a62001-04-23 14:08:49 +000033iter_dealloc(seqiterobject *it)
Guido van Rossum05311482001-04-20 21:06:46 +000034{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000035 _PyObject_GC_UNTRACK(it);
36 Py_XDECREF(it->it_seq);
37 PyObject_GC_Del(it);
Guido van Rossum05311482001-04-20 21:06:46 +000038}
39
Neil Schemenauer7eac9b72001-07-12 13:27:25 +000040static int
41iter_traverse(seqiterobject *it, visitproc visit, void *arg)
42{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000043 Py_VISIT(it->it_seq);
44 return 0;
Neil Schemenauer7eac9b72001-07-12 13:27:25 +000045}
46
Guido van Rossum05311482001-04-20 21:06:46 +000047static PyObject *
Guido van Rossum213c7a62001-04-23 14:08:49 +000048iter_iternext(PyObject *iterator)
49{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000050 seqiterobject *it;
51 PyObject *seq;
52 PyObject *result;
Guido van Rossum213c7a62001-04-23 14:08:49 +000053
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000054 assert(PySeqIter_Check(iterator));
55 it = (seqiterobject *)iterator;
56 seq = it->it_seq;
57 if (seq == NULL)
58 return NULL;
Serhiy Storchaka4faf5c52015-05-21 20:50:25 +030059 if (it->it_index == PY_SSIZE_T_MAX) {
60 PyErr_SetString(PyExc_OverflowError,
61 "iter index too large");
62 return NULL;
63 }
Guido van Rossum213c7a62001-04-23 14:08:49 +000064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000065 result = PySequence_GetItem(seq, it->it_index);
66 if (result != NULL) {
67 it->it_index++;
68 return result;
69 }
70 if (PyErr_ExceptionMatches(PyExc_IndexError) ||
71 PyErr_ExceptionMatches(PyExc_StopIteration))
72 {
73 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000074 it->it_seq = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030075 Py_DECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000076 }
77 return NULL;
Guido van Rossum213c7a62001-04-23 14:08:49 +000078}
79
Raymond Hettinger6b27cda2005-09-24 21:23:05 +000080static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +053081iter_len(seqiterobject *it, PyObject *Py_UNUSED(ignored))
Raymond Hettinger435bf582004-03-18 22:43:10 +000082{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 Py_ssize_t seqsize, len;
Raymond Hettinger7892b1c2004-04-12 18:10:01 +000084
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085 if (it->it_seq) {
Armin Ronacheraa9a79d2012-10-06 14:03:24 +020086 if (_PyObject_HasLen(it->it_seq)) {
87 seqsize = PySequence_Size(it->it_seq);
88 if (seqsize == -1)
89 return NULL;
90 }
91 else {
Armin Ronacher23c5bb42012-10-06 14:30:32 +020092 Py_RETURN_NOTIMPLEMENTED;
Armin Ronacheraa9a79d2012-10-06 14:03:24 +020093 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000094 len = seqsize - it->it_index;
95 if (len >= 0)
96 return PyLong_FromSsize_t(len);
97 }
98 return PyLong_FromLong(0);
Raymond Hettinger435bf582004-03-18 22:43:10 +000099}
100
Armin Rigof5b3e362006-02-11 21:32:43 +0000101PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000102
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000103static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530104iter_reduce(seqiterobject *it, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000105{
106 if (it->it_seq != NULL)
Antoine Pitroua7013882012-04-05 00:04:20 +0200107 return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000108 it->it_seq, it->it_index);
109 else
Antoine Pitroua7013882012-04-05 00:04:20 +0200110 return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter"));
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000111}
112
113PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
114
115static PyObject *
116iter_setstate(seqiterobject *it, PyObject *state)
117{
118 Py_ssize_t index = PyLong_AsSsize_t(state);
119 if (index == -1 && PyErr_Occurred())
120 return NULL;
121 if (it->it_seq != NULL) {
122 if (index < 0)
123 index = 0;
124 it->it_index = index;
125 }
126 Py_RETURN_NONE;
127}
128
129PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
130
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000131static PyMethodDef seqiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000132 {"__length_hint__", (PyCFunction)iter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000133 {"__reduce__", (PyCFunction)iter_reduce, METH_NOARGS, reduce_doc},
134 {"__setstate__", (PyCFunction)iter_setstate, METH_O, setstate_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 {NULL, NULL} /* sentinel */
Raymond Hettinger435bf582004-03-18 22:43:10 +0000136};
137
Guido van Rossum213c7a62001-04-23 14:08:49 +0000138PyTypeObject PySeqIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 PyVarObject_HEAD_INIT(&PyType_Type, 0)
140 "iterator", /* tp_name */
141 sizeof(seqiterobject), /* tp_basicsize */
142 0, /* tp_itemsize */
143 /* methods */
144 (destructor)iter_dealloc, /* tp_dealloc */
145 0, /* tp_print */
146 0, /* tp_getattr */
147 0, /* tp_setattr */
148 0, /* tp_reserved */
149 0, /* tp_repr */
150 0, /* tp_as_number */
151 0, /* tp_as_sequence */
152 0, /* tp_as_mapping */
153 0, /* tp_hash */
154 0, /* tp_call */
155 0, /* tp_str */
156 PyObject_GenericGetAttr, /* tp_getattro */
157 0, /* tp_setattro */
158 0, /* tp_as_buffer */
159 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
160 0, /* tp_doc */
161 (traverseproc)iter_traverse, /* tp_traverse */
162 0, /* tp_clear */
163 0, /* tp_richcompare */
164 0, /* tp_weaklistoffset */
165 PyObject_SelfIter, /* tp_iter */
166 iter_iternext, /* tp_iternext */
167 seqiter_methods, /* tp_methods */
168 0, /* tp_members */
Guido van Rossum05311482001-04-20 21:06:46 +0000169};
170
171/* -------------------------------------- */
172
173typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000174 PyObject_HEAD
175 PyObject *it_callable; /* Set to NULL when iterator is exhausted */
176 PyObject *it_sentinel; /* Set to NULL when iterator is exhausted */
Guido van Rossum05311482001-04-20 21:06:46 +0000177} calliterobject;
178
179PyObject *
180PyCallIter_New(PyObject *callable, PyObject *sentinel)
181{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182 calliterobject *it;
183 it = PyObject_GC_New(calliterobject, &PyCallIter_Type);
184 if (it == NULL)
185 return NULL;
186 Py_INCREF(callable);
187 it->it_callable = callable;
188 Py_INCREF(sentinel);
189 it->it_sentinel = sentinel;
190 _PyObject_GC_TRACK(it);
191 return (PyObject *)it;
Guido van Rossum05311482001-04-20 21:06:46 +0000192}
193static void
194calliter_dealloc(calliterobject *it)
195{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000196 _PyObject_GC_UNTRACK(it);
197 Py_XDECREF(it->it_callable);
198 Py_XDECREF(it->it_sentinel);
199 PyObject_GC_Del(it);
Guido van Rossum05311482001-04-20 21:06:46 +0000200}
Guido van Rossum213c7a62001-04-23 14:08:49 +0000201
Neil Schemenauer7eac9b72001-07-12 13:27:25 +0000202static int
203calliter_traverse(calliterobject *it, visitproc visit, void *arg)
204{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 Py_VISIT(it->it_callable);
206 Py_VISIT(it->it_sentinel);
207 return 0;
Neil Schemenauer7eac9b72001-07-12 13:27:25 +0000208}
209
Guido van Rossum05311482001-04-20 21:06:46 +0000210static PyObject *
Guido van Rossum213c7a62001-04-23 14:08:49 +0000211calliter_iternext(calliterobject *it)
212{
Victor Stinner99ee9c72016-08-19 18:47:10 +0200213 PyObject *result;
214
215 if (it->it_callable == NULL) {
216 return NULL;
217 }
218
Victor Stinner559bb6a2016-08-22 22:48:54 +0200219 result = _PyObject_CallNoArg(it->it_callable);
Victor Stinner99ee9c72016-08-19 18:47:10 +0200220 if (result != NULL) {
221 int ok;
222
223 ok = PyObject_RichCompareBool(it->it_sentinel, result, Py_EQ);
224 if (ok == 0) {
225 return result; /* Common case, fast path */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 }
Victor Stinner99ee9c72016-08-19 18:47:10 +0200227
228 Py_DECREF(result);
229 if (ok > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 Py_CLEAR(it->it_callable);
231 Py_CLEAR(it->it_sentinel);
232 }
233 }
Victor Stinner99ee9c72016-08-19 18:47:10 +0200234 else if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
235 PyErr_Clear();
236 Py_CLEAR(it->it_callable);
237 Py_CLEAR(it->it_sentinel);
238 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 return NULL;
Guido van Rossum213c7a62001-04-23 14:08:49 +0000240}
241
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000242static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530243calliter_reduce(calliterobject *it, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000244{
245 if (it->it_callable != NULL && it->it_sentinel != NULL)
Antoine Pitroua7013882012-04-05 00:04:20 +0200246 return Py_BuildValue("N(OO)", _PyObject_GetBuiltin("iter"),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000247 it->it_callable, it->it_sentinel);
248 else
Antoine Pitroua7013882012-04-05 00:04:20 +0200249 return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter"));
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000250}
251
252static PyMethodDef calliter_methods[] = {
253 {"__reduce__", (PyCFunction)calliter_reduce, METH_NOARGS, reduce_doc},
254 {NULL, NULL} /* sentinel */
255};
256
Guido van Rossum05311482001-04-20 21:06:46 +0000257PyTypeObject PyCallIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000258 PyVarObject_HEAD_INIT(&PyType_Type, 0)
259 "callable_iterator", /* tp_name */
260 sizeof(calliterobject), /* tp_basicsize */
261 0, /* tp_itemsize */
262 /* methods */
263 (destructor)calliter_dealloc, /* tp_dealloc */
264 0, /* tp_print */
265 0, /* tp_getattr */
266 0, /* tp_setattr */
267 0, /* tp_reserved */
268 0, /* tp_repr */
269 0, /* tp_as_number */
270 0, /* tp_as_sequence */
271 0, /* tp_as_mapping */
272 0, /* tp_hash */
273 0, /* tp_call */
274 0, /* tp_str */
275 PyObject_GenericGetAttr, /* tp_getattro */
276 0, /* tp_setattro */
277 0, /* tp_as_buffer */
278 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
279 0, /* tp_doc */
280 (traverseproc)calliter_traverse, /* tp_traverse */
281 0, /* tp_clear */
282 0, /* tp_richcompare */
283 0, /* tp_weaklistoffset */
284 PyObject_SelfIter, /* tp_iter */
285 (iternextfunc)calliter_iternext, /* tp_iternext */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000286 calliter_methods, /* tp_methods */
Guido van Rossum05311482001-04-20 21:06:46 +0000287};
Guido van Rossumb65fb332006-08-25 23:26:40 +0000288
289