99
1010import unittest
1111import inspect
12+ import sys
13+ import types
1214
1315from test .support import captured_stderr , disable_gc , gc_collect
1416from test import support
@@ -18,6 +20,83 @@ class TestPEP380Operation(unittest.TestCase):
1820 Test semantics.
1921 """
2022
23+ def test_delegated_throw_preserves_exception_state (self ):
24+ """Delegated throw inherits the delegating generator's exception."""
25+ class Iterator :
26+ def __init__ (self , gen ):
27+ self .gen = gen
28+
29+ def __iter__ (self ):
30+ return self
31+
32+ def __next__ (self ):
33+ return next (self .gen )
34+
35+ def throw (self , * args ):
36+ return self .gen .throw (* args )
37+
38+ for wrap in (lambda gen : gen , Iterator ):
39+ with self .subTest (wrap = wrap ):
40+ original = RuntimeError ("original" )
41+ seen = []
42+
43+ def inner ():
44+ seen .append (sys .exception ())
45+ try :
46+ yield
47+ except ValueError :
48+ pass
49+ seen .append (sys .exception ())
50+ yield
51+
52+ def outer ():
53+ try :
54+ raise original
55+ except RuntimeError :
56+ yield from wrap (inner ())
57+ seen .append (sys .exception ())
58+
59+ gen = outer ()
60+ next (gen )
61+ try :
62+ raise LookupError ("caller" )
63+ except LookupError as caller :
64+ gen .throw (ValueError ())
65+ self .assertIs (sys .exception (), caller )
66+ with self .assertRaises (StopIteration ):
67+ next (gen )
68+ self .assertIs (sys .exception (), caller )
69+ self .assertEqual (seen , [original ] * 3 )
70+
71+ def test_await_throw_preserves_exception_state (self ):
72+ """Throwing through await preserves the surrounding handled exception."""
73+ original = RuntimeError ("original" )
74+ seen = []
75+
76+ @types .coroutine
77+ def suspend ():
78+ yield
79+
80+ async def inner ():
81+ try :
82+ await suspend ()
83+ except ValueError :
84+ pass
85+ seen .append (sys .exception ())
86+
87+ async def outer ():
88+ try :
89+ raise original
90+ except RuntimeError :
91+ await inner ()
92+ seen .append (sys .exception ())
93+
94+ coro = outer ()
95+ coro .send (None )
96+ with self .assertRaises (StopIteration ):
97+ coro .throw (ValueError ())
98+ self .assertEqual (seen , [original ] * 2 )
99+
21100 def test_delegation_of_initial_next_to_subgenerator (self ):
22101 """
23102 Test delegation of initial next() call to subgenerator
0 commit comments