mirror of https://github.com/python/cpython
gh-126366: Fix crash if `__iter__` raises an exception during `yield from` (#126369)
This commit is contained in:
parent
407c0366d9
commit
1371295e67
|
@ -1576,6 +1576,19 @@ class TestInterestingEdgeCases(unittest.TestCase):
|
||||||
self.assertIsNone(caught.exception.__context__)
|
self.assertIsNone(caught.exception.__context__)
|
||||||
self.assert_stop_iteration(g)
|
self.assert_stop_iteration(g)
|
||||||
|
|
||||||
|
def test_throws_in_iter(self):
|
||||||
|
# See GH-126366: NULL pointer dereference if __iter__
|
||||||
|
# threw an exception.
|
||||||
|
class Silly:
|
||||||
|
def __iter__(self):
|
||||||
|
raise RuntimeError("nobody expects the spanish inquisition")
|
||||||
|
|
||||||
|
def my_generator():
|
||||||
|
yield from Silly()
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(RuntimeError, "nobody expects the spanish inquisition"):
|
||||||
|
next(iter(my_generator()))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix crash when using ``yield from`` on an object that raises an exception in
|
||||||
|
its ``__iter__``.
|
|
@ -2811,11 +2811,12 @@ dummy_func(
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* `iterable` is not a generator. */
|
/* `iterable` is not a generator. */
|
||||||
iter = PyStackRef_FromPyObjectSteal(PyObject_GetIter(iterable_o));
|
PyObject *iter_o = PyObject_GetIter(iterable_o);
|
||||||
DEAD(iterable);
|
DEAD(iterable);
|
||||||
if (PyStackRef_IsNull(iter)) {
|
if (iter_o == NULL) {
|
||||||
ERROR_NO_POP();
|
ERROR_NO_POP();
|
||||||
}
|
}
|
||||||
|
iter = PyStackRef_FromPyObjectSteal(iter_o);
|
||||||
DECREF_INPUTS();
|
DECREF_INPUTS();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3437,11 +3437,12 @@
|
||||||
else {
|
else {
|
||||||
/* `iterable` is not a generator. */
|
/* `iterable` is not a generator. */
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
iter = PyStackRef_FromPyObjectSteal(PyObject_GetIter(iterable_o));
|
PyObject *iter_o = PyObject_GetIter(iterable_o);
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
if (PyStackRef_IsNull(iter)) {
|
if (iter_o == NULL) {
|
||||||
JUMP_TO_ERROR();
|
JUMP_TO_ERROR();
|
||||||
}
|
}
|
||||||
|
iter = PyStackRef_FromPyObjectSteal(iter_o);
|
||||||
PyStackRef_CLOSE(iterable);
|
PyStackRef_CLOSE(iterable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4304,11 +4304,12 @@
|
||||||
else {
|
else {
|
||||||
/* `iterable` is not a generator. */
|
/* `iterable` is not a generator. */
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
iter = PyStackRef_FromPyObjectSteal(PyObject_GetIter(iterable_o));
|
PyObject *iter_o = PyObject_GetIter(iterable_o);
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
if (PyStackRef_IsNull(iter)) {
|
if (iter_o == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
iter = PyStackRef_FromPyObjectSteal(iter_o);
|
||||||
PyStackRef_CLOSE(iterable);
|
PyStackRef_CLOSE(iterable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ test.test_socket.RecvmsgSCMRightsStreamTest.testCmsgTruncLen1
|
||||||
test.test_socket.RecvmsgSCMRightsStreamTest.testCmsgTruncLen2Minus1
|
test.test_socket.RecvmsgSCMRightsStreamTest.testCmsgTruncLen2Minus1
|
||||||
test.test_subprocess.POSIXProcessTestCase.test_exception_bad_args_0
|
test.test_subprocess.POSIXProcessTestCase.test_exception_bad_args_0
|
||||||
test.test_subprocess.POSIXProcessTestCase.test_exception_bad_executable
|
test.test_subprocess.POSIXProcessTestCase.test_exception_bad_executable
|
||||||
|
test.test_subprocess.POSIXProcessTestCase.test_vfork_used_when_expected
|
||||||
test.test_subprocess.ProcessTestCase.test_cwd_with_relative_arg
|
test.test_subprocess.ProcessTestCase.test_cwd_with_relative_arg
|
||||||
test.test_subprocess.ProcessTestCase.test_cwd_with_relative_executable
|
test.test_subprocess.ProcessTestCase.test_cwd_with_relative_executable
|
||||||
test.test_subprocess.ProcessTestCase.test_empty_env
|
test.test_subprocess.ProcessTestCase.test_empty_env
|
||||||
|
|
Loading…
Reference in New Issue