Skip to content

Commit 3e53ac9

Browse files
authored
gh-103186: Suppress and assert expected RuntimeWarnings in test_sys_settrace (GH-103244)
Caused as a result of frame manipulation where locals are never assigned / initialised.
1 parent babdced commit 3e53ac9

File tree

2 files changed

+43
-32
lines changed

2 files changed

+43
-32
lines changed

Lib/test/test_sys_settrace.py

+42-32
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from functools import wraps
99
import asyncio
1010
from test.support import import_helper
11+
import contextlib
1112

1213
support.requires_working_socket(module=True)
1314

@@ -1922,6 +1923,8 @@ def no_jump_without_trace_function():
19221923

19231924

19241925
class JumpTestCase(unittest.TestCase):
1926+
unbound_locals = r"assigning None to [0-9]+ unbound local"
1927+
19251928
def setUp(self):
19261929
self.addCleanup(sys.settrace, sys.gettrace())
19271930
sys.settrace(None)
@@ -1933,53 +1936,59 @@ def compare_jump_output(self, expected, received):
19331936
"Received: " + repr(received))
19341937

19351938
def run_test(self, func, jumpFrom, jumpTo, expected, error=None,
1936-
event='line', decorated=False):
1939+
event='line', decorated=False, warning=None):
19371940
tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated)
19381941
sys.settrace(tracer.trace)
19391942
output = []
1940-
if error is None:
1943+
1944+
with contextlib.ExitStack() as stack:
1945+
if error is not None:
1946+
stack.enter_context(self.assertRaisesRegex(*error))
1947+
if warning is not None:
1948+
stack.enter_context(self.assertWarnsRegex(*warning))
19411949
func(output)
1942-
else:
1943-
with self.assertRaisesRegex(*error):
1944-
func(output)
1950+
19451951
sys.settrace(None)
19461952
self.compare_jump_output(expected, output)
19471953

19481954
def run_async_test(self, func, jumpFrom, jumpTo, expected, error=None,
1949-
event='line', decorated=False):
1955+
event='line', decorated=False, warning=None):
19501956
tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated)
19511957
sys.settrace(tracer.trace)
19521958
output = []
1953-
if error is None:
1959+
1960+
with contextlib.ExitStack() as stack:
1961+
if error is not None:
1962+
stack.enter_context(self.assertRaisesRegex(*error))
1963+
if warning is not None:
1964+
stack.enter_context(self.assertWarnsRegex(*warning))
19541965
asyncio.run(func(output))
1955-
else:
1956-
with self.assertRaisesRegex(*error):
1957-
asyncio.run(func(output))
1966+
19581967
sys.settrace(None)
19591968
asyncio.set_event_loop_policy(None)
19601969
self.compare_jump_output(expected, output)
19611970

1962-
def jump_test(jumpFrom, jumpTo, expected, error=None, event='line'):
1971+
def jump_test(jumpFrom, jumpTo, expected, error=None, event='line', warning=None):
19631972
"""Decorator that creates a test that makes a jump
19641973
from one place to another in the following code.
19651974
"""
19661975
def decorator(func):
19671976
@wraps(func)
19681977
def test(self):
19691978
self.run_test(func, jumpFrom, jumpTo, expected,
1970-
error=error, event=event, decorated=True)
1979+
error=error, event=event, decorated=True, warning=warning)
19711980
return test
19721981
return decorator
19731982

1974-
def async_jump_test(jumpFrom, jumpTo, expected, error=None, event='line'):
1983+
def async_jump_test(jumpFrom, jumpTo, expected, error=None, event='line', warning=None):
19751984
"""Decorator that creates a test that makes a jump
19761985
from one place to another in the following asynchronous code.
19771986
"""
19781987
def decorator(func):
19791988
@wraps(func)
19801989
def test(self):
19811990
self.run_async_test(func, jumpFrom, jumpTo, expected,
1982-
error=error, event=event, decorated=True)
1991+
error=error, event=event, decorated=True, warning=warning)
19831992
return test
19841993
return decorator
19851994

@@ -1996,7 +2005,7 @@ def test_jump_simple_backwards(output):
19962005
output.append(1)
19972006
output.append(2)
19982007

1999-
@jump_test(3, 5, [2, 5])
2008+
@jump_test(3, 5, [2, 5], warning=(RuntimeWarning, unbound_locals))
20002009
def test_jump_out_of_block_forwards(output):
20012010
for i in 1, 2:
20022011
output.append(2)
@@ -2210,7 +2219,7 @@ def test_jump_within_except_block(output):
22102219
output.append(6)
22112220
output.append(7)
22122221

2213-
@jump_test(6, 1, [1, 5, 1, 5])
2222+
@jump_test(6, 1, [1, 5, 1, 5], warning=(RuntimeWarning, unbound_locals))
22142223
def test_jump_over_try_except(output):
22152224
output.append(1)
22162225
try:
@@ -2306,15 +2315,15 @@ def test_jump_out_of_complex_nested_blocks(output):
23062315
output.append(11)
23072316
output.append(12)
23082317

2309-
@jump_test(3, 5, [1, 2, 5])
2318+
@jump_test(3, 5, [1, 2, 5], warning=(RuntimeWarning, unbound_locals))
23102319
def test_jump_out_of_with_assignment(output):
23112320
output.append(1)
23122321
with tracecontext(output, 2) \
23132322
as x:
23142323
output.append(4)
23152324
output.append(5)
23162325

2317-
@async_jump_test(3, 5, [1, 2, 5])
2326+
@async_jump_test(3, 5, [1, 2, 5], warning=(RuntimeWarning, unbound_locals))
23182327
async def test_jump_out_of_async_with_assignment(output):
23192328
output.append(1)
23202329
async with asynctracecontext(output, 2) \
@@ -2350,7 +2359,7 @@ def test_jump_over_break_in_try_finally_block(output):
23502359
break
23512360
output.append(13)
23522361

2353-
@jump_test(1, 7, [7, 8])
2362+
@jump_test(1, 7, [7, 8], warning=(RuntimeWarning, unbound_locals))
23542363
def test_jump_over_for_block_before_else(output):
23552364
output.append(1)
23562365
if not output: # always false
@@ -2361,7 +2370,7 @@ def test_jump_over_for_block_before_else(output):
23612370
output.append(7)
23622371
output.append(8)
23632372

2364-
@async_jump_test(1, 7, [7, 8])
2373+
@async_jump_test(1, 7, [7, 8], warning=(RuntimeWarning, unbound_locals))
23652374
async def test_jump_over_async_for_block_before_else(output):
23662375
output.append(1)
23672376
if not output: # always false
@@ -2436,6 +2445,7 @@ def test_no_jump_backwards_into_for_block(output):
24362445
output.append(2)
24372446
output.append(3)
24382447

2448+
24392449
@async_jump_test(3, 2, [2, 2], (ValueError, "can't jump into the body of a for loop"))
24402450
async def test_no_jump_backwards_into_async_for_block(output):
24412451
async for i in asynciter([1, 2]):
@@ -2501,7 +2511,7 @@ def test_jump_backwards_into_try_except_block(output):
25012511
output.append(6)
25022512

25032513
# 'except' with a variable creates an implicit finally block
2504-
@jump_test(5, 7, [4, 7, 8])
2514+
@jump_test(5, 7, [4, 7, 8], warning=(RuntimeWarning, unbound_locals))
25052515
def test_jump_between_except_blocks_2(output):
25062516
try:
25072517
1/0
@@ -2664,7 +2674,7 @@ def test_large_function(self):
26642674
output.append(x) # line 1007
26652675
return""" % ('\n' * 1000,), d)
26662676
f = d['f']
2667-
self.run_test(f, 2, 1007, [0])
2677+
self.run_test(f, 2, 1007, [0], warning=(RuntimeWarning, self.unbound_locals))
26682678

26692679
def test_jump_to_firstlineno(self):
26702680
# This tests that PDB can jump back to the first line in a
@@ -2714,21 +2724,21 @@ def gen():
27142724
next(gen())
27152725
output.append(5)
27162726

2717-
@jump_test(2, 3, [1, 3])
2727+
@jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals))
27182728
def test_jump_forward_over_listcomp(output):
27192729
output.append(1)
27202730
x = [i for i in range(10)]
27212731
output.append(3)
27222732

27232733
# checking for segfaults.
27242734
# See https://github.com/python/cpython/issues/92311
2725-
@jump_test(3, 1, [])
2735+
@jump_test(3, 1, [], warning=(RuntimeWarning, unbound_locals))
27262736
def test_jump_backward_over_listcomp(output):
27272737
a = 1
27282738
x = [i for i in range(10)]
27292739
c = 3
27302740

2731-
@jump_test(8, 2, [2, 7, 2])
2741+
@jump_test(8, 2, [2, 7, 2], warning=(RuntimeWarning, unbound_locals))
27322742
def test_jump_backward_over_listcomp_v2(output):
27332743
flag = False
27342744
output.append(2)
@@ -2739,19 +2749,19 @@ def test_jump_backward_over_listcomp_v2(output):
27392749
output.append(7)
27402750
output.append(8)
27412751

2742-
@async_jump_test(2, 3, [1, 3])
2752+
@async_jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals))
27432753
async def test_jump_forward_over_async_listcomp(output):
27442754
output.append(1)
27452755
x = [i async for i in asynciter(range(10))]
27462756
output.append(3)
27472757

2748-
@async_jump_test(3, 1, [])
2758+
@async_jump_test(3, 1, [], warning=(RuntimeWarning, unbound_locals))
27492759
async def test_jump_backward_over_async_listcomp(output):
27502760
a = 1
27512761
x = [i async for i in asynciter(range(10))]
27522762
c = 3
27532763

2754-
@async_jump_test(8, 2, [2, 7, 2])
2764+
@async_jump_test(8, 2, [2, 7, 2], warning=(RuntimeWarning, unbound_locals))
27552765
async def test_jump_backward_over_async_listcomp_v2(output):
27562766
flag = False
27572767
output.append(2)
@@ -2820,13 +2830,13 @@ def test_jump_with_null_on_stack_load_attr(output):
28202830
)
28212831
output.append(15)
28222832

2823-
@jump_test(2, 3, [1, 3])
2833+
@jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals))
28242834
def test_jump_extended_args_unpack_ex_simple(output):
28252835
output.append(1)
28262836
_, *_, _ = output.append(2) or "Spam"
28272837
output.append(3)
28282838

2829-
@jump_test(3, 4, [1, 4, 4, 5])
2839+
@jump_test(3, 4, [1, 4, 4, 5], warning=(RuntimeWarning, unbound_locals))
28302840
def test_jump_extended_args_unpack_ex_tricky(output):
28312841
output.append(1)
28322842
(
@@ -2848,9 +2858,9 @@ def test_jump_extended_args_for_iter(self):
28482858
namespace = {}
28492859
exec("\n".join(source), namespace)
28502860
f = namespace["f"]
2851-
self.run_test(f, 2, 100_000, [1, 100_000])
2861+
self.run_test(f, 2, 100_000, [1, 100_000], warning=(RuntimeWarning, self.unbound_locals))
28522862

2853-
@jump_test(2, 3, [1, 3])
2863+
@jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals))
28542864
def test_jump_or_pop(output):
28552865
output.append(1)
28562866
_ = output.append(2) and "Spam"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Suppress and assert expected RuntimeWarnings in test_sys_settrace.py

0 commit comments

Comments
 (0)