Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit06a3bb8

Browse files
miss-islingtonworkingpayloadarhadthedev
authored
gh-101892: FixSystemError when a callable iterator call exhausts the iterator (GH-101896)
(cherry picked from commit705487c)Co-authored-by: Raj <51259329+workingpayload@users.noreply.github.com>Co-authored-by: Oleg Iarygin <oleg@arhadthedev.net>
1 parent00791f2 commit06a3bb8

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

‎Lib/test/test_iter.py‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,31 @@ def spam(state=[0]):
348348
returni
349349
self.check_iterator(iter(spam,20),list(range(10)),pickle=False)
350350

351+
deftest_iter_function_concealing_reentrant_exhaustion(self):
352+
# gh-101892: Test two-argument iter() with a function that
353+
# exhausts its associated iterator but forgets to either return
354+
# a sentinel value or raise StopIteration.
355+
HAS_MORE=1
356+
NO_MORE=2
357+
358+
defexhaust(iterator):
359+
"""Exhaust an iterator without raising StopIteration."""
360+
list(iterator)
361+
362+
defspam():
363+
# Touching the iterator with exhaust() below will call
364+
# spam() once again so protect against recursion.
365+
ifspam.is_recursive_call:
366+
returnNO_MORE
367+
spam.is_recursive_call=True
368+
exhaust(spam.iterator)
369+
returnHAS_MORE
370+
371+
spam.is_recursive_call=False
372+
spam.iterator=iter(spam,NO_MORE)
373+
withself.assertRaises(StopIteration):
374+
next(spam.iterator)
375+
351376
# Test exception propagation through function iterator
352377
deftest_exception_function(self):
353378
defspam(state=[0]):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Callable iterators no longer raise:class:`SystemError` when the
2+
callable object exhausts the iterator but forgets to either return a
3+
sentinel value or raise:class:`StopIteration`.

‎Objects/iterobject.c‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,15 +222,14 @@ calliter_iternext(calliterobject *it)
222222
}
223223

224224
result=_PyObject_CallNoArgs(it->it_callable);
225-
if (result!=NULL){
225+
if (result!=NULL&&it->it_sentinel!=NULL){
226226
intok;
227227

228228
ok=PyObject_RichCompareBool(it->it_sentinel,result,Py_EQ);
229229
if (ok==0) {
230230
returnresult;/* Common case, fast path */
231231
}
232232

233-
Py_DECREF(result);
234233
if (ok>0) {
235234
Py_CLEAR(it->it_callable);
236235
Py_CLEAR(it->it_sentinel);
@@ -241,6 +240,7 @@ calliter_iternext(calliterobject *it)
241240
Py_CLEAR(it->it_callable);
242241
Py_CLEAR(it->it_sentinel);
243242
}
243+
Py_XDECREF(result);
244244
returnNULL;
245245
}
246246

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp