88from functools import wraps
99import asyncio
1010from test .support import import_helper
11+ import contextlib
1112
1213support .requires_working_socket (module = True )
1314
@@ -1900,6 +1901,8 @@ def no_jump_without_trace_function():
19001901
19011902
19021903class JumpTestCase (unittest .TestCase ):
1904+ unbound_locals = r"assigning None to [0-9]+ unbound local"
1905+
19031906 def setUp (self ):
19041907 self .addCleanup (sys .settrace , sys .gettrace ())
19051908 sys .settrace (None )
@@ -1911,53 +1914,59 @@ def compare_jump_output(self, expected, received):
19111914 "Received: " + repr (received ))
19121915
19131916 def run_test (self , func , jumpFrom , jumpTo , expected , error = None ,
1914- event = 'line' , decorated = False ):
1917+ event = 'line' , decorated = False , warning = None ):
19151918 tracer = JumpTracer (func , jumpFrom , jumpTo , event , decorated )
19161919 sys .settrace (tracer .trace )
19171920 output = []
1918- if error is None :
1921+
1922+ with contextlib .ExitStack () as stack :
1923+ if error is not None :
1924+ stack .enter_context (self .assertRaisesRegex (* error ))
1925+ if warning is not None :
1926+ stack .enter_context (self .assertWarnsRegex (* warning ))
19191927 func (output )
1920- else :
1921- with self .assertRaisesRegex (* error ):
1922- func (output )
1928+
19231929 sys .settrace (None )
19241930 self .compare_jump_output (expected , output )
19251931
19261932 def run_async_test (self , func , jumpFrom , jumpTo , expected , error = None ,
1927- event = 'line' , decorated = False ):
1933+ event = 'line' , decorated = False , warning = None ):
19281934 tracer = JumpTracer (func , jumpFrom , jumpTo , event , decorated )
19291935 sys .settrace (tracer .trace )
19301936 output = []
1931- if error is None :
1937+
1938+ with contextlib .ExitStack () as stack :
1939+ if error is not None :
1940+ stack .enter_context (self .assertRaisesRegex (* error ))
1941+ if warning is not None :
1942+ stack .enter_context (self .assertWarnsRegex (* warning ))
19321943 asyncio .run (func (output ))
1933- else :
1934- with self .assertRaisesRegex (* error ):
1935- asyncio .run (func (output ))
1944+
19361945 sys .settrace (None )
19371946 asyncio .set_event_loop_policy (None )
19381947 self .compare_jump_output (expected , output )
19391948
1940- def jump_test (jumpFrom , jumpTo , expected , error = None , event = 'line' ):
1949+ def jump_test (jumpFrom , jumpTo , expected , error = None , event = 'line' , warning = None ):
19411950 """Decorator that creates a test that makes a jump
19421951 from one place to another in the following code.
19431952 """
19441953 def decorator (func ):
19451954 @wraps (func )
19461955 def test (self ):
19471956 self .run_test (func , jumpFrom , jumpTo , expected ,
1948- error = error , event = event , decorated = True )
1957+ error = error , event = event , decorated = True , warning = warning )
19491958 return test
19501959 return decorator
19511960
1952- def async_jump_test (jumpFrom , jumpTo , expected , error = None , event = 'line' ):
1961+ def async_jump_test (jumpFrom , jumpTo , expected , error = None , event = 'line' , warning = None ):
19531962 """Decorator that creates a test that makes a jump
19541963 from one place to another in the following asynchronous code.
19551964 """
19561965 def decorator (func ):
19571966 @wraps (func )
19581967 def test (self ):
19591968 self .run_async_test (func , jumpFrom , jumpTo , expected ,
1960- error = error , event = event , decorated = True )
1969+ error = error , event = event , decorated = True , warning = warning )
19611970 return test
19621971 return decorator
19631972
@@ -1974,7 +1983,7 @@ def test_jump_simple_backwards(output):
19741983 output .append (1 )
19751984 output .append (2 )
19761985
1977- @jump_test (3 , 5 , [2 , 5 ])
1986+ @jump_test (3 , 5 , [2 , 5 ], warning = ( RuntimeWarning , unbound_locals ) )
19781987 def test_jump_out_of_block_forwards (output ):
19791988 for i in 1 , 2 :
19801989 output .append (2 )
@@ -2188,7 +2197,7 @@ def test_jump_within_except_block(output):
21882197 output .append (6 )
21892198 output .append (7 )
21902199
2191- @jump_test (6 , 1 , [1 , 5 , 1 , 5 ])
2200+ @jump_test (6 , 1 , [1 , 5 , 1 , 5 ], warning = ( RuntimeWarning , unbound_locals ) )
21922201 def test_jump_over_try_except (output ):
21932202 output .append (1 )
21942203 try :
@@ -2284,15 +2293,15 @@ def test_jump_out_of_complex_nested_blocks(output):
22842293 output .append (11 )
22852294 output .append (12 )
22862295
2287- @jump_test (3 , 5 , [1 , 2 , 5 ])
2296+ @jump_test (3 , 5 , [1 , 2 , 5 ], warning = ( RuntimeWarning , unbound_locals ) )
22882297 def test_jump_out_of_with_assignment (output ):
22892298 output .append (1 )
22902299 with tracecontext (output , 2 ) \
22912300 as x :
22922301 output .append (4 )
22932302 output .append (5 )
22942303
2295- @async_jump_test (3 , 5 , [1 , 2 , 5 ])
2304+ @async_jump_test (3 , 5 , [1 , 2 , 5 ], warning = ( RuntimeWarning , unbound_locals ) )
22962305 async def test_jump_out_of_async_with_assignment (output ):
22972306 output .append (1 )
22982307 async with asynctracecontext (output , 2 ) \
@@ -2328,7 +2337,7 @@ def test_jump_over_break_in_try_finally_block(output):
23282337 break
23292338 output .append (13 )
23302339
2331- @jump_test (1 , 7 , [7 , 8 ])
2340+ @jump_test (1 , 7 , [7 , 8 ], warning = ( RuntimeWarning , unbound_locals ) )
23322341 def test_jump_over_for_block_before_else (output ):
23332342 output .append (1 )
23342343 if not output : # always false
@@ -2339,7 +2348,7 @@ def test_jump_over_for_block_before_else(output):
23392348 output .append (7 )
23402349 output .append (8 )
23412350
2342- @async_jump_test (1 , 7 , [7 , 8 ])
2351+ @async_jump_test (1 , 7 , [7 , 8 ], warning = ( RuntimeWarning , unbound_locals ) )
23432352 async def test_jump_over_async_for_block_before_else (output ):
23442353 output .append (1 )
23452354 if not output : # always false
@@ -2414,6 +2423,7 @@ def test_no_jump_backwards_into_for_block(output):
24142423 output .append (2 )
24152424 output .append (3 )
24162425
2426+
24172427 @async_jump_test (3 , 2 , [2 , 2 ], (ValueError , "can't jump into the body of a for loop" ))
24182428 async def test_no_jump_backwards_into_async_for_block (output ):
24192429 async for i in asynciter ([1 , 2 ]):
@@ -2479,7 +2489,7 @@ def test_jump_backwards_into_try_except_block(output):
24792489 output .append (6 )
24802490
24812491 # 'except' with a variable creates an implicit finally block
2482- @jump_test (5 , 7 , [4 , 7 , 8 ])
2492+ @jump_test (5 , 7 , [4 , 7 , 8 ], warning = ( RuntimeWarning , unbound_locals ) )
24832493 def test_jump_between_except_blocks_2 (output ):
24842494 try :
24852495 1 / 0
@@ -2642,7 +2652,7 @@ def test_large_function(self):
26422652 output.append(x) # line 1007
26432653 return""" % ('\n ' * 1000 ,), d )
26442654 f = d ['f' ]
2645- self .run_test (f , 2 , 1007 , [0 ])
2655+ self .run_test (f , 2 , 1007 , [0 ], warning = ( RuntimeWarning , self . unbound_locals ) )
26462656
26472657 def test_jump_to_firstlineno (self ):
26482658 # This tests that PDB can jump back to the first line in a
@@ -2692,21 +2702,21 @@ def gen():
26922702 next (gen ())
26932703 output .append (5 )
26942704
2695- @jump_test (2 , 3 , [1 , 3 ])
2705+ @jump_test (2 , 3 , [1 , 3 ], warning = ( RuntimeWarning , unbound_locals ) )
26962706 def test_jump_forward_over_listcomp (output ):
26972707 output .append (1 )
26982708 x = [i for i in range (10 )]
26992709 output .append (3 )
27002710
27012711 # checking for segfaults.
27022712 # See https://github.com/python/cpython/issues/92311
2703- @jump_test (3 , 1 , [])
2713+ @jump_test (3 , 1 , [], warning = ( RuntimeWarning , unbound_locals ) )
27042714 def test_jump_backward_over_listcomp (output ):
27052715 a = 1
27062716 x = [i for i in range (10 )]
27072717 c = 3
27082718
2709- @jump_test (8 , 2 , [2 , 7 , 2 ])
2719+ @jump_test (8 , 2 , [2 , 7 , 2 ], warning = ( RuntimeWarning , unbound_locals ) )
27102720 def test_jump_backward_over_listcomp_v2 (output ):
27112721 flag = False
27122722 output .append (2 )
@@ -2717,19 +2727,19 @@ def test_jump_backward_over_listcomp_v2(output):
27172727 output .append (7 )
27182728 output .append (8 )
27192729
2720- @async_jump_test (2 , 3 , [1 , 3 ])
2730+ @async_jump_test (2 , 3 , [1 , 3 ], warning = ( RuntimeWarning , unbound_locals ) )
27212731 async def test_jump_forward_over_async_listcomp (output ):
27222732 output .append (1 )
27232733 x = [i async for i in asynciter (range (10 ))]
27242734 output .append (3 )
27252735
2726- @async_jump_test (3 , 1 , [])
2736+ @async_jump_test (3 , 1 , [], warning = ( RuntimeWarning , unbound_locals ) )
27272737 async def test_jump_backward_over_async_listcomp (output ):
27282738 a = 1
27292739 x = [i async for i in asynciter (range (10 ))]
27302740 c = 3
27312741
2732- @async_jump_test (8 , 2 , [2 , 7 , 2 ])
2742+ @async_jump_test (8 , 2 , [2 , 7 , 2 ], warning = ( RuntimeWarning , unbound_locals ) )
27332743 async def test_jump_backward_over_async_listcomp_v2 (output ):
27342744 flag = False
27352745 output .append (2 )
@@ -2798,13 +2808,13 @@ def test_jump_with_null_on_stack_load_attr(output):
27982808 )
27992809 output .append (15 )
28002810
2801- @jump_test (2 , 3 , [1 , 3 ])
2811+ @jump_test (2 , 3 , [1 , 3 ], warning = ( RuntimeWarning , unbound_locals ) )
28022812 def test_jump_extended_args_unpack_ex_simple (output ):
28032813 output .append (1 )
28042814 _ , * _ , _ = output .append (2 ) or "Spam"
28052815 output .append (3 )
28062816
2807- @jump_test (3 , 4 , [1 , 4 , 4 , 5 ])
2817+ @jump_test (3 , 4 , [1 , 4 , 4 , 5 ], warning = ( RuntimeWarning , unbound_locals ) )
28082818 def test_jump_extended_args_unpack_ex_tricky (output ):
28092819 output .append (1 )
28102820 (
@@ -2826,9 +2836,9 @@ def test_jump_extended_args_for_iter(self):
28262836 namespace = {}
28272837 exec ("\n " .join (source ), namespace )
28282838 f = namespace ["f" ]
2829- self .run_test (f , 2 , 100_000 , [1 , 100_000 ])
2839+ self .run_test (f , 2 , 100_000 , [1 , 100_000 ], warning = ( RuntimeWarning , self . unbound_locals ) )
28302840
2831- @jump_test (2 , 3 , [1 , 3 ])
2841+ @jump_test (2 , 3 , [1 , 3 ], warning = ( RuntimeWarning , unbound_locals ) )
28322842 def test_jump_or_pop (output ):
28332843 output .append (1 )
28342844 _ = output .append (2 ) and "Spam"
0 commit comments