@@ -143,15 +143,46 @@ async def f():
143143 self .assertEqual (frames [0 ].line , '1/0' )
144144
145145 # Repeat with RuntimeError (which goes through a different code path)
146+ class RuntimeErrorSubclass (RuntimeError ):
147+ pass
148+
146149 try :
147150 async with f ():
148- raise NotImplementedError (42 )
149- except NotImplementedError as e :
151+ raise RuntimeErrorSubclass (42 )
152+ except RuntimeErrorSubclass as e :
150153 frames = traceback .extract_tb (e .__traceback__ )
151154
152155 self .assertEqual (len (frames ), 1 )
153156 self .assertEqual (frames [0 ].name , 'test_contextmanager_traceback' )
154- self .assertEqual (frames [0 ].line , 'raise NotImplementedError(42)' )
157+ self .assertEqual (frames [0 ].line , 'raise RuntimeErrorSubclass(42)' )
158+
159+ class StopIterationSubclass (StopIteration ):
160+ pass
161+
162+ class StopAsyncIterationSubclass (StopAsyncIteration ):
163+ pass
164+
165+ for stop_exc in (
166+ StopIteration ('spam' ),
167+ StopAsyncIteration ('ham' ),
168+ StopIterationSubclass ('spam' ),
169+ StopAsyncIterationSubclass ('spam' )
170+ ):
171+ with self .subTest (type = type (stop_exc )):
172+ try :
173+ async with f ():
174+ raise stop_exc
175+ except type (stop_exc ) as e :
176+ self .assertIs (e , stop_exc )
177+ frames = traceback .extract_tb (e .__traceback__ )
178+ else :
179+ self .fail (f'{ stop_exc } was suppressed' )
180+
181+ self .assertEqual (len (frames ), 2 )
182+ self .assertEqual (frames [0 ].name , 'f' )
183+ self .assertEqual (frames [0 ].line , 'yield' )
184+ self .assertEqual (frames [1 ].name , 'test_contextmanager_traceback' )
185+ self .assertEqual (frames [1 ].line , 'raise stop_exc' )
155186
156187 @_async_test
157188 async def test_contextmanager_no_reraise (self ):
0 commit comments