blob: 06a6da5695f8a698166df09a071fd23f5f479f91 [file] [log] [blame]
Guido van Rossum05311482001-04-20 21:06:46 +00001/* Iterator objects */
2
3#include "Python.h"
Victor Stinnerbcda8f12018-11-21 22:27:47 +01004#include "pycore_object.h"
Guido van Rossum05311482001-04-20 21:06:46 +00005
6typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00007 PyObject_HEAD
Victor Stinnere0b99ba2013-06-04 23:02:46 +02008 Py_ssize_t it_index;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00009 PyObject *it_seq; /* Set to NULL when iterator is exhausted */
Guido van Rossum213c7a62001-04-23 14:08:49 +000010} seqiterobject;
Guido van Rossum05311482001-04-20 21:06:46 +000011
Hai Shi46874c22020-01-30 17:20:25 -060012_Py_IDENTIFIER(iter);
13
Guido van Rossum05311482001-04-20 21:06:46 +000014PyObject *
Guido van Rossum213c7a62001-04-23 14:08:49 +000015PySeqIter_New(PyObject *seq)
Guido van Rossum05311482001-04-20 21:06:46 +000016{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000017 seqiterobject *it;
Martin v. Löwis01f94bd2002-05-08 08:44:21 +000018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000019 if (!PySequence_Check(seq)) {
20 PyErr_BadInternalCall();
21 return NULL;
22 }
23 it = PyObject_GC_New(seqiterobject, &PySeqIter_Type);
24 if (it == NULL)
25 return NULL;
26 it->it_index = 0;
27 Py_INCREF(seq);
28 it->it_seq = seq;
29 _PyObject_GC_TRACK(it);
30 return (PyObject *)it;
Guido van Rossum05311482001-04-20 21:06:46 +000031}
Guido van Rossum613bed32002-07-16 20:24:46 +000032
Guido van Rossum05311482001-04-20 21:06:46 +000033static void
Guido van Rossum213c7a62001-04-23 14:08:49 +000034iter_dealloc(seqiterobject *it)
Guido van Rossum05311482001-04-20 21:06:46 +000035{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000036 _PyObject_GC_UNTRACK(it);
37 Py_XDECREF(it->it_seq);
38 PyObject_GC_Del(it);
Guido van Rossum05311482001-04-20 21:06:46 +000039}
40
Neil Schemenauer7eac9b72001-07-12 13:27:25 +000041static int
42iter_traverse(seqiterobject *it, visitproc visit, void *arg)
43{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000044 Py_VISIT(it->it_seq);
45 return 0;
Neil Schemenauer7eac9b72001-07-12 13:27:25 +000046}
47
Guido van Rossum05311482001-04-20 21:06:46 +000048static PyObject *
Guido van Rossum213c7a62001-04-23 14:08:49 +000049iter_iternext(PyObject *iterator)
50{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000051 seqiterobject *it;
52 PyObject *seq;
53 PyObject *result;
Guido van Rossum213c7a62001-04-23 14:08:49 +000054
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000055 assert(PySeqIter_Check(iterator));
56 it = (seqiterobject *)iterator;
57 seq = it->it_seq;
58 if (seq == NULL)
59 return NULL;
Serhiy Storchaka4faf5c52015-05-21 20:50:25 +030060 if (it->it_index == PY_SSIZE_T_MAX) {
61 PyErr_SetString(PyExc_OverflowError,
62 "iter index too large");
63 return NULL;
64 }
Guido van Rossum213c7a62001-04-23 14:08:49 +000065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066 result = PySequence_GetItem(seq, it->it_index);
67 if (result != NULL) {
68 it->it_index++;
69 return result;
70 }
71 if (PyErr_ExceptionMatches(PyExc_IndexError) ||
72 PyErr_ExceptionMatches(PyExc_StopIteration))
73 {
74 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000075 it->it_seq = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030076 Py_DECREF(seq);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000077 }
78 return NULL;
Guido van Rossum213c7a62001-04-23 14:08:49 +000079}
80
Raymond Hettinger6b27cda2005-09-24 21:23:05 +000081static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +053082iter_len(seqiterobject *it, PyObject *Py_UNUSED(ignored))
Raymond Hettinger435bf582004-03-18 22:43:10 +000083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 Py_ssize_t seqsize, len;
Raymond Hettinger7892b1c2004-04-12 18:10:01 +000085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000086 if (it->it_seq) {
Armin Ronacheraa9a79d2012-10-06 14:03:24 +020087 if (_PyObject_HasLen(it->it_seq)) {
88 seqsize = PySequence_Size(it->it_seq);
89 if (seqsize == -1)
90 return NULL;
91 }
92 else {
Armin Ronacher23c5bb42012-10-06 14:30:32 +020093 Py_RETURN_NOTIMPLEMENTED;
Armin Ronacheraa9a79d2012-10-06 14:03:24 +020094 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 len = seqsize - it->it_index;
96 if (len >= 0)
97 return PyLong_FromSsize_t(len);
98 }
99 return PyLong_FromLong(0);
Raymond Hettinger435bf582004-03-18 22:43:10 +0000100}
101
Armin Rigof5b3e362006-02-11 21:32:43 +0000102PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000103
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000104static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530105iter_reduce(seqiterobject *it, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000106{
107 if (it->it_seq != NULL)
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200108 return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000109 it->it_seq, it->it_index);
110 else
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200111 return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter));
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000112}
113
114PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
115
116static PyObject *
117iter_setstate(seqiterobject *it, PyObject *state)
118{
119 Py_ssize_t index = PyLong_AsSsize_t(state);
120 if (index == -1 && PyErr_Occurred())
121 return NULL;
122 if (it->it_seq != NULL) {
123 if (index < 0)
124 index = 0;
125 it->it_index = index;
126 }
127 Py_RETURN_NONE;
128}
129
130PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
131
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000132static PyMethodDef seqiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 {"__length_hint__", (PyCFunction)iter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000134 {"__reduce__", (PyCFunction)iter_reduce, METH_NOARGS, reduce_doc},
135 {"__setstate__", (PyCFunction)iter_setstate, METH_O, setstate_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000136 {NULL, NULL} /* sentinel */
Raymond Hettinger435bf582004-03-18 22:43:10 +0000137};
138
Guido van Rossum213c7a62001-04-23 14:08:49 +0000139PyTypeObject PySeqIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000140 PyVarObject_HEAD_INIT(&PyType_Type, 0)
141 "iterator", /* tp_name */
142 sizeof(seqiterobject), /* tp_basicsize */
143 0, /* tp_itemsize */
144 /* methods */
145 (destructor)iter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200146 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000147 0, /* tp_getattr */
148 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200149 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 0, /* tp_repr */
151 0, /* tp_as_number */
152 0, /* tp_as_sequence */
153 0, /* tp_as_mapping */
154 0, /* tp_hash */
155 0, /* tp_call */
156 0, /* tp_str */
157 PyObject_GenericGetAttr, /* tp_getattro */
158 0, /* tp_setattro */
159 0, /* tp_as_buffer */
Joshua Bronsonf0a6fde2021-03-23 18:47:21 -0400160 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000161 0, /* tp_doc */
162 (traverseproc)iter_traverse, /* tp_traverse */
163 0, /* tp_clear */
164 0, /* tp_richcompare */
165 0, /* tp_weaklistoffset */
166 PyObject_SelfIter, /* tp_iter */
167 iter_iternext, /* tp_iternext */
168 seqiter_methods, /* tp_methods */
169 0, /* tp_members */
Guido van Rossum05311482001-04-20 21:06:46 +0000170};
171
172/* -------------------------------------- */
173
174typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 PyObject_HEAD
176 PyObject *it_callable; /* Set to NULL when iterator is exhausted */
177 PyObject *it_sentinel; /* Set to NULL when iterator is exhausted */
Guido van Rossum05311482001-04-20 21:06:46 +0000178} calliterobject;
179
180PyObject *
181PyCallIter_New(PyObject *callable, PyObject *sentinel)
182{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000183 calliterobject *it;
184 it = PyObject_GC_New(calliterobject, &PyCallIter_Type);
185 if (it == NULL)
186 return NULL;
187 Py_INCREF(callable);
188 it->it_callable = callable;
189 Py_INCREF(sentinel);
190 it->it_sentinel = sentinel;
191 _PyObject_GC_TRACK(it);
192 return (PyObject *)it;
Guido van Rossum05311482001-04-20 21:06:46 +0000193}
194static void
195calliter_dealloc(calliterobject *it)
196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 _PyObject_GC_UNTRACK(it);
198 Py_XDECREF(it->it_callable);
199 Py_XDECREF(it->it_sentinel);
200 PyObject_GC_Del(it);
Guido van Rossum05311482001-04-20 21:06:46 +0000201}
Guido van Rossum213c7a62001-04-23 14:08:49 +0000202
Neil Schemenauer7eac9b72001-07-12 13:27:25 +0000203static int
204calliter_traverse(calliterobject *it, visitproc visit, void *arg)
205{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 Py_VISIT(it->it_callable);
207 Py_VISIT(it->it_sentinel);
208 return 0;
Neil Schemenauer7eac9b72001-07-12 13:27:25 +0000209}
210
Guido van Rossum05311482001-04-20 21:06:46 +0000211static PyObject *
Guido van Rossum213c7a62001-04-23 14:08:49 +0000212calliter_iternext(calliterobject *it)
213{
Victor Stinner99ee9c72016-08-19 18:47:10 +0200214 PyObject *result;
215
216 if (it->it_callable == NULL) {
217 return NULL;
218 }
219
Victor Stinner559bb6a2016-08-22 22:48:54 +0200220 result = _PyObject_CallNoArg(it->it_callable);
Victor Stinner99ee9c72016-08-19 18:47:10 +0200221 if (result != NULL) {
222 int ok;
223
224 ok = PyObject_RichCompareBool(it->it_sentinel, result, Py_EQ);
225 if (ok == 0) {
226 return result; /* Common case, fast path */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 }
Victor Stinner99ee9c72016-08-19 18:47:10 +0200228
229 Py_DECREF(result);
230 if (ok > 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 Py_CLEAR(it->it_callable);
232 Py_CLEAR(it->it_sentinel);
233 }
234 }
Victor Stinner99ee9c72016-08-19 18:47:10 +0200235 else if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
236 PyErr_Clear();
237 Py_CLEAR(it->it_callable);
238 Py_CLEAR(it->it_sentinel);
239 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000240 return NULL;
Guido van Rossum213c7a62001-04-23 14:08:49 +0000241}
242
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000243static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530244calliter_reduce(calliterobject *it, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000245{
246 if (it->it_callable != NULL && it->it_sentinel != NULL)
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200247 return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_iter),
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000248 it->it_callable, it->it_sentinel);
249 else
Serhiy Storchakabb86bf42018-12-11 08:28:18 +0200250 return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter));
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000251}
252
253static PyMethodDef calliter_methods[] = {
254 {"__reduce__", (PyCFunction)calliter_reduce, METH_NOARGS, reduce_doc},
255 {NULL, NULL} /* sentinel */
256};
257
Guido van Rossum05311482001-04-20 21:06:46 +0000258PyTypeObject PyCallIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 PyVarObject_HEAD_INIT(&PyType_Type, 0)
260 "callable_iterator", /* tp_name */
261 sizeof(calliterobject), /* tp_basicsize */
262 0, /* tp_itemsize */
263 /* methods */
264 (destructor)calliter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200265 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 0, /* tp_getattr */
267 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200268 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 0, /* tp_repr */
270 0, /* tp_as_number */
271 0, /* tp_as_sequence */
272 0, /* tp_as_mapping */
273 0, /* tp_hash */
274 0, /* tp_call */
275 0, /* tp_str */
276 PyObject_GenericGetAttr, /* tp_getattro */
277 0, /* tp_setattro */
278 0, /* tp_as_buffer */
Joshua Bronsonf0a6fde2021-03-23 18:47:21 -0400279 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 0, /* tp_doc */
281 (traverseproc)calliter_traverse, /* tp_traverse */
282 0, /* tp_clear */
283 0, /* tp_richcompare */
284 0, /* tp_weaklistoffset */
285 PyObject_SelfIter, /* tp_iter */
286 (iternextfunc)calliter_iternext, /* tp_iternext */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000287 calliter_methods, /* tp_methods */
Guido van Rossum05311482001-04-20 21:06:46 +0000288};
Guido van Rossumb65fb332006-08-25 23:26:40 +0000289
290
Joshua Bronsonf0a6fde2021-03-23 18:47:21 -0400291/* -------------------------------------- */
292
293typedef struct {
294 PyObject_HEAD
295 PyObject *wrapped;
296 PyObject *default_value;
297} anextawaitableobject;
298
299static void
300anextawaitable_dealloc(anextawaitableobject *obj)
301{
302 _PyObject_GC_UNTRACK(obj);
303 Py_XDECREF(obj->wrapped);
304 Py_XDECREF(obj->default_value);
305 PyObject_GC_Del(obj);
306}
307
308static int
309anextawaitable_traverse(anextawaitableobject *obj, visitproc visit, void *arg)
310{
311 Py_VISIT(obj->wrapped);
312 Py_VISIT(obj->default_value);
313 return 0;
314}
315
316static PyObject *
317anextawaitable_iternext(anextawaitableobject *obj)
318{
319 PyObject *result = PyIter_Next(obj->wrapped);
320 if (result != NULL) {
321 return result;
322 }
323 if (PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) {
324 _PyGen_SetStopIterationValue(obj->default_value);
325 }
326 return NULL;
327}
328
329static PyAsyncMethods anextawaitable_as_async = {
330 PyObject_SelfIter, /* am_await */
331 0, /* am_aiter */
332 0, /* am_anext */
333 0, /* am_send */
334};
335
336PyTypeObject PyAnextAwaitable_Type = {
337 PyVarObject_HEAD_INIT(&PyType_Type, 0)
338 "anext_awaitable", /* tp_name */
339 sizeof(anextawaitableobject), /* tp_basicsize */
340 0, /* tp_itemsize */
341 /* methods */
342 (destructor)anextawaitable_dealloc, /* tp_dealloc */
343 0, /* tp_vectorcall_offset */
344 0, /* tp_getattr */
345 0, /* tp_setattr */
346 &anextawaitable_as_async, /* tp_as_async */
347 0, /* tp_repr */
348 0, /* tp_as_number */
349 0, /* tp_as_sequence */
350 0, /* tp_as_mapping */
351 0, /* tp_hash */
352 0, /* tp_call */
353 0, /* tp_str */
354 PyObject_GenericGetAttr, /* tp_getattro */
355 0, /* tp_setattro */
356 0, /* tp_as_buffer */
357 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
358 0, /* tp_doc */
359 (traverseproc)anextawaitable_traverse, /* tp_traverse */
360 0, /* tp_clear */
361 0, /* tp_richcompare */
362 0, /* tp_weaklistoffset */
363 PyObject_SelfIter, /* tp_iter */
364 (unaryfunc)anextawaitable_iternext, /* tp_iternext */
365 0, /* tp_methods */
366};
367
368PyObject *
369PyAnextAwaitable_New(PyObject *awaitable, PyObject *default_value)
370{
371 anextawaitableobject *anext = PyObject_GC_New(anextawaitableobject, &PyAnextAwaitable_Type);
372 Py_INCREF(awaitable);
373 anext->wrapped = awaitable;
374 Py_INCREF(default_value);
375 anext->default_value = default_value;
376 _PyObject_GC_TRACK(anext);
377 return (PyObject *)anext;
378}