Skip to content

Commit edc54c8

Browse files
committed
make PyIter_NextItem return 0 for exhausted iterator and 1 when it provides a new value
1 parent 5aaf37e commit edc54c8

5 files changed

Lines changed: 15 additions & 8 deletions

File tree

Doc/c-api/iter.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ something like this::
4040
4141
PyObject *item;
4242
int res;
43-
while ((res = PyIter_NextItem(iterator, &item)) == 0 && item != NULL) {
43+
while ((res = PyIter_NextItem(iterator, &item)) == 1) {
4444
/* do something with item */
4545
...
4646
/* release reference when done */

Include/abstract.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,8 @@ PyAPI_FUNC(int) PyAIter_Check(PyObject *);
401401
setting *item to the next value, or to NULL if the iterator
402402
is exhausted.
403403
404-
Return 0 on success and -1 on error. */
404+
Return 1 if *item was set to a new value, 0 if the iterator is
405+
exhausted and -1 on error. */
405406
PyAPI_FUNC(int) PyIter_NextItem(PyObject *iter, PyObject **item);
406407

407408
/* Takes an iterator object and calls its tp_iternext slot,

Modules/_testcapimodule.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,14 @@ call_pyiter_nextitem(PyObject* self, PyObject *args)
310310
if (ret < 0) {
311311
return NULL;
312312
}
313-
if (item == NULL) {
313+
else if (ret == 0) {
314+
assert(item == NULL);
314315
assert(!PyErr_Occurred());
315316
Py_RETURN_NONE;
316317
}
318+
assert(ret == 1);
319+
assert(item != NULL);
320+
assert(!PyErr_Occurred());
317321
return item;
318322
}
319323

Modules/_xxtestfuzz/fuzzer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ static int fuzz_csv_reader(const char* data, size_t size) {
377377
if (reader) {
378378
/* Consume all of the reader as an iterator */
379379
PyObject* parsed_line;
380-
while (PyIter_NextItem(reader, &parsed_line) == 0) {
380+
while (PyIter_NextItem(reader, &parsed_line) == 1) {
381381
Py_DECREF(parsed_line);
382382
}
383383
}

Objects/abstract.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2833,9 +2833,10 @@ PyAIter_Check(PyObject *obj)
28332833
tp->tp_as_async->am_anext != &_PyObject_NextNotImplemented);
28342834
}
28352835

2836-
/* Set *item to the next item. Return 0 on success and -1 on error.
2837-
* If the iteration terminates normally, set *item to NULL and clear
2838-
* the PyExc_StopIteration exception (if it was set).
2836+
/* If the iterator has another value to return, set *item to this value
2837+
* and return 1.
2838+
* If the iterator is exhausted, set *item to NULL and return 0.
2839+
* On error (other than StopIteration) from tp_iternext, return -1.
28392840
*/
28402841
int
28412842
PyIter_NextItem(PyObject *iter, PyObject **item)
@@ -2852,8 +2853,9 @@ PyIter_NextItem(PyObject *iter, PyObject **item)
28522853
return -1;
28532854
}
28542855
}
2856+
return 0;
28552857
}
2856-
return 0;
2858+
return 1;
28572859
}
28582860

28592861
/* Return next item.

0 commit comments

Comments
 (0)