Skip to content

Commit 1371295

Browse files
gh-126366: Fix crash if __iter__ raises an exception during yield from (#126369)
1 parent 407c036 commit 1371295

File tree

6 files changed

+25
-6
lines changed

6 files changed

+25
-6
lines changed

Lib/test/test_yield_from.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,6 +1576,19 @@ def outer():
15761576
self.assertIsNone(caught.exception.__context__)
15771577
self.assert_stop_iteration(g)
15781578

1579+
def test_throws_in_iter(self):
1580+
# See GH-126366: NULL pointer dereference if __iter__
1581+
# threw an exception.
1582+
class Silly:
1583+
def __iter__(self):
1584+
raise RuntimeError("nobody expects the spanish inquisition")
1585+
1586+
def my_generator():
1587+
yield from Silly()
1588+
1589+
with self.assertRaisesRegex(RuntimeError, "nobody expects the spanish inquisition"):
1590+
next(iter(my_generator()))
1591+
15791592

15801593
if __name__ == '__main__':
15811594
unittest.main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix crash when using ``yield from`` on an object that raises an exception in
2+
its ``__iter__``.

Python/bytecodes.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2811,11 +2811,12 @@ dummy_func(
28112811
}
28122812
else {
28132813
/* `iterable` is not a generator. */
2814-
iter = PyStackRef_FromPyObjectSteal(PyObject_GetIter(iterable_o));
2814+
PyObject *iter_o = PyObject_GetIter(iterable_o);
28152815
DEAD(iterable);
2816-
if (PyStackRef_IsNull(iter)) {
2816+
if (iter_o == NULL) {
28172817
ERROR_NO_POP();
28182818
}
2819+
iter = PyStackRef_FromPyObjectSteal(iter_o);
28192820
DECREF_INPUTS();
28202821
}
28212822
}

Python/executor_cases.c.h

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/jit/ignore-tests-emulated-linux.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ test.test_socket.RecvmsgSCMRightsStreamTest.testCmsgTruncLen1
7171
test.test_socket.RecvmsgSCMRightsStreamTest.testCmsgTruncLen2Minus1
7272
test.test_subprocess.POSIXProcessTestCase.test_exception_bad_args_0
7373
test.test_subprocess.POSIXProcessTestCase.test_exception_bad_executable
74+
test.test_subprocess.POSIXProcessTestCase.test_vfork_used_when_expected
7475
test.test_subprocess.ProcessTestCase.test_cwd_with_relative_arg
7576
test.test_subprocess.ProcessTestCase.test_cwd_with_relative_executable
7677
test.test_subprocess.ProcessTestCase.test_empty_env

0 commit comments

Comments
 (0)