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

Commitfe36778

Browse files
[3.10]gh-101892: FixSystemError when a callable iterator call exhausts the iterator (GH-101896) (#102422)
gh-101892: Fix `SystemError` when a callable iterator call exhausts the iterator (#101896)Co-authored-by: Oleg Iarygin <oleg@arhadthedev.net>(cherry picked from commit705487c)Co-authored-by: Raj <51259329+workingpayload@users.noreply.github.com>
1 parent6c2e052 commitfe36778

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
@@ -346,6 +346,31 @@ def spam(state=[0]):
346346
returni
347347
self.check_iterator(iter(spam,20),list(range(10)),pickle=False)
348348

349+
deftest_iter_function_concealing_reentrant_exhaustion(self):
350+
# gh-101892: Test two-argument iter() with a function that
351+
# exhausts its associated iterator but forgets to either return
352+
# a sentinel value or raise StopIteration.
353+
HAS_MORE=1
354+
NO_MORE=2
355+
356+
defexhaust(iterator):
357+
"""Exhaust an iterator without raising StopIteration."""
358+
list(iterator)
359+
360+
defspam():
361+
# Touching the iterator with exhaust() below will call
362+
# spam() once again so protect against recursion.
363+
ifspam.is_recursive_call:
364+
returnNO_MORE
365+
spam.is_recursive_call=True
366+
exhaust(spam.iterator)
367+
returnHAS_MORE
368+
369+
spam.is_recursive_call=False
370+
spam.iterator=iter(spam,NO_MORE)
371+
withself.assertRaises(StopIteration):
372+
next(spam.iterator)
373+
349374
# Test exception propagation through function iterator
350375
deftest_exception_function(self):
351376
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
@@ -223,15 +223,14 @@ calliter_iternext(calliterobject *it)
223223
}
224224

225225
result=_PyObject_CallNoArg(it->it_callable);
226-
if (result!=NULL){
226+
if (result!=NULL&&it->it_sentinel!=NULL){
227227
intok;
228228

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

234-
Py_DECREF(result);
235234
if (ok>0) {
236235
Py_CLEAR(it->it_callable);
237236
Py_CLEAR(it->it_sentinel);
@@ -242,6 +241,7 @@ calliter_iternext(calliterobject *it)
242241
Py_CLEAR(it->it_callable);
243242
Py_CLEAR(it->it_sentinel);
244243
}
244+
Py_XDECREF(result);
245245
returnNULL;
246246
}
247247

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp