2 Commits

Author SHA1 Message Date
Changjoon
6b67067e9a Chain __context__ alongside __cause__ when wrapping StopIteration (PEP 479) (#7731)
PEP 479 wraps a StopIteration raised from a generator/coroutine into a
RuntimeError. CPython sets both __cause__ and __context__ of the new
RuntimeError to the original StopIteration (the same object). RustPython's
wrapping sites set __cause__ only, leaving __context__ as None.

set___cause__ already toggles __suppress_context__ to true, so the
user-facing traceback is unchanged — only assertions that inspect
__context__ directly observe the gap.

Three sites all wrap StopIteration / StopAsyncIteration into RuntimeError
for PEP 479. Set __context__ to the same exception instance before
setting __cause__ at each:

- frame.rs::StopIterationError intrinsic (generator yield-expression path)
- coroutine.rs generator __next__ StopIteration branch
- coroutine.rs async-generator __anext__ StopAsyncIteration branch

PyBaseExceptionRef is Arc-backed, so e.clone() is a refcount bump;
'cause is context' holds, matching CPython.

Unmasks:
- test_generator_stop.TestPEP479.test_stopiteration_wrapping_context
- test_yield_from.TestInterestingEdgeCases.test_close_and_throw_work
- test_yield_from.TestInterestingEdgeCases.test_close_and_throw_raise_stop_iteration
- test_yield_from.TestInterestingEdgeCases.test_close_and_throw_yield
2026-04-29 18:52:22 +09:00
ShaharNaveh
fcd1bb6e9b Add test_generator_stop.py from 3.14.3 2026-03-12 13:19:19 +01:00