mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
babdced23f
commit
3e53ac9903
|
@ -8,6 +8,7 @@ import gc
|
|||
from functools import wraps
|
||||
import asyncio
|
||||
from test.support import import_helper
|
||||
import contextlib
|
||||
|
||||
support.requires_working_socket(module=True)
|
||||
|
||||
|
@ -1922,6 +1923,8 @@ def no_jump_without_trace_function():
|
|||
|
||||
|
||||
class JumpTestCase(unittest.TestCase):
|
||||
unbound_locals = r"assigning None to [0-9]+ unbound local"
|
||||
|
||||
def setUp(self):
|
||||
self.addCleanup(sys.settrace, sys.gettrace())
|
||||
sys.settrace(None)
|
||||
|
@ -1933,33 +1936,39 @@ class JumpTestCase(unittest.TestCase):
|
|||
"Received: " + repr(received))
|
||||
|
||||
def run_test(self, func, jumpFrom, jumpTo, expected, error=None,
|
||||
event='line', decorated=False):
|
||||
event='line', decorated=False, warning=None):
|
||||
tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated)
|
||||
sys.settrace(tracer.trace)
|
||||
output = []
|
||||
if error is None:
|
||||
|
||||
with contextlib.ExitStack() as stack:
|
||||
if error is not None:
|
||||
stack.enter_context(self.assertRaisesRegex(*error))
|
||||
if warning is not None:
|
||||
stack.enter_context(self.assertWarnsRegex(*warning))
|
||||
func(output)
|
||||
else:
|
||||
with self.assertRaisesRegex(*error):
|
||||
func(output)
|
||||
|
||||
sys.settrace(None)
|
||||
self.compare_jump_output(expected, output)
|
||||
|
||||
def run_async_test(self, func, jumpFrom, jumpTo, expected, error=None,
|
||||
event='line', decorated=False):
|
||||
event='line', decorated=False, warning=None):
|
||||
tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated)
|
||||
sys.settrace(tracer.trace)
|
||||
output = []
|
||||
if error is None:
|
||||
|
||||
with contextlib.ExitStack() as stack:
|
||||
if error is not None:
|
||||
stack.enter_context(self.assertRaisesRegex(*error))
|
||||
if warning is not None:
|
||||
stack.enter_context(self.assertWarnsRegex(*warning))
|
||||
asyncio.run(func(output))
|
||||
else:
|
||||
with self.assertRaisesRegex(*error):
|
||||
asyncio.run(func(output))
|
||||
|
||||
sys.settrace(None)
|
||||
asyncio.set_event_loop_policy(None)
|
||||
self.compare_jump_output(expected, output)
|
||||
|
||||
def jump_test(jumpFrom, jumpTo, expected, error=None, event='line'):
|
||||
def jump_test(jumpFrom, jumpTo, expected, error=None, event='line', warning=None):
|
||||
"""Decorator that creates a test that makes a jump
|
||||
from one place to another in the following code.
|
||||
"""
|
||||
|
@ -1967,11 +1976,11 @@ class JumpTestCase(unittest.TestCase):
|
|||
@wraps(func)
|
||||
def test(self):
|
||||
self.run_test(func, jumpFrom, jumpTo, expected,
|
||||
error=error, event=event, decorated=True)
|
||||
error=error, event=event, decorated=True, warning=warning)
|
||||
return test
|
||||
return decorator
|
||||
|
||||
def async_jump_test(jumpFrom, jumpTo, expected, error=None, event='line'):
|
||||
def async_jump_test(jumpFrom, jumpTo, expected, error=None, event='line', warning=None):
|
||||
"""Decorator that creates a test that makes a jump
|
||||
from one place to another in the following asynchronous code.
|
||||
"""
|
||||
|
@ -1979,7 +1988,7 @@ class JumpTestCase(unittest.TestCase):
|
|||
@wraps(func)
|
||||
def test(self):
|
||||
self.run_async_test(func, jumpFrom, jumpTo, expected,
|
||||
error=error, event=event, decorated=True)
|
||||
error=error, event=event, decorated=True, warning=warning)
|
||||
return test
|
||||
return decorator
|
||||
|
||||
|
@ -1996,7 +2005,7 @@ class JumpTestCase(unittest.TestCase):
|
|||
output.append(1)
|
||||
output.append(2)
|
||||
|
||||
@jump_test(3, 5, [2, 5])
|
||||
@jump_test(3, 5, [2, 5], warning=(RuntimeWarning, unbound_locals))
|
||||
def test_jump_out_of_block_forwards(output):
|
||||
for i in 1, 2:
|
||||
output.append(2)
|
||||
|
@ -2210,7 +2219,7 @@ class JumpTestCase(unittest.TestCase):
|
|||
output.append(6)
|
||||
output.append(7)
|
||||
|
||||
@jump_test(6, 1, [1, 5, 1, 5])
|
||||
@jump_test(6, 1, [1, 5, 1, 5], warning=(RuntimeWarning, unbound_locals))
|
||||
def test_jump_over_try_except(output):
|
||||
output.append(1)
|
||||
try:
|
||||
|
@ -2306,7 +2315,7 @@ class JumpTestCase(unittest.TestCase):
|
|||
output.append(11)
|
||||
output.append(12)
|
||||
|
||||
@jump_test(3, 5, [1, 2, 5])
|
||||
@jump_test(3, 5, [1, 2, 5], warning=(RuntimeWarning, unbound_locals))
|
||||
def test_jump_out_of_with_assignment(output):
|
||||
output.append(1)
|
||||
with tracecontext(output, 2) \
|
||||
|
@ -2314,7 +2323,7 @@ class JumpTestCase(unittest.TestCase):
|
|||
output.append(4)
|
||||
output.append(5)
|
||||
|
||||
@async_jump_test(3, 5, [1, 2, 5])
|
||||
@async_jump_test(3, 5, [1, 2, 5], warning=(RuntimeWarning, unbound_locals))
|
||||
async def test_jump_out_of_async_with_assignment(output):
|
||||
output.append(1)
|
||||
async with asynctracecontext(output, 2) \
|
||||
|
@ -2350,7 +2359,7 @@ class JumpTestCase(unittest.TestCase):
|
|||
break
|
||||
output.append(13)
|
||||
|
||||
@jump_test(1, 7, [7, 8])
|
||||
@jump_test(1, 7, [7, 8], warning=(RuntimeWarning, unbound_locals))
|
||||
def test_jump_over_for_block_before_else(output):
|
||||
output.append(1)
|
||||
if not output: # always false
|
||||
|
@ -2361,7 +2370,7 @@ class JumpTestCase(unittest.TestCase):
|
|||
output.append(7)
|
||||
output.append(8)
|
||||
|
||||
@async_jump_test(1, 7, [7, 8])
|
||||
@async_jump_test(1, 7, [7, 8], warning=(RuntimeWarning, unbound_locals))
|
||||
async def test_jump_over_async_for_block_before_else(output):
|
||||
output.append(1)
|
||||
if not output: # always false
|
||||
|
@ -2436,6 +2445,7 @@ class JumpTestCase(unittest.TestCase):
|
|||
output.append(2)
|
||||
output.append(3)
|
||||
|
||||
|
||||
@async_jump_test(3, 2, [2, 2], (ValueError, "can't jump into the body of a for loop"))
|
||||
async def test_no_jump_backwards_into_async_for_block(output):
|
||||
async for i in asynciter([1, 2]):
|
||||
|
@ -2501,7 +2511,7 @@ class JumpTestCase(unittest.TestCase):
|
|||
output.append(6)
|
||||
|
||||
# 'except' with a variable creates an implicit finally block
|
||||
@jump_test(5, 7, [4, 7, 8])
|
||||
@jump_test(5, 7, [4, 7, 8], warning=(RuntimeWarning, unbound_locals))
|
||||
def test_jump_between_except_blocks_2(output):
|
||||
try:
|
||||
1/0
|
||||
|
@ -2664,7 +2674,7 @@ class JumpTestCase(unittest.TestCase):
|
|||
output.append(x) # line 1007
|
||||
return""" % ('\n' * 1000,), d)
|
||||
f = d['f']
|
||||
self.run_test(f, 2, 1007, [0])
|
||||
self.run_test(f, 2, 1007, [0], warning=(RuntimeWarning, self.unbound_locals))
|
||||
|
||||
def test_jump_to_firstlineno(self):
|
||||
# This tests that PDB can jump back to the first line in a
|
||||
|
@ -2714,7 +2724,7 @@ output.append(4)
|
|||
next(gen())
|
||||
output.append(5)
|
||||
|
||||
@jump_test(2, 3, [1, 3])
|
||||
@jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals))
|
||||
def test_jump_forward_over_listcomp(output):
|
||||
output.append(1)
|
||||
x = [i for i in range(10)]
|
||||
|
@ -2722,13 +2732,13 @@ output.append(4)
|
|||
|
||||
# checking for segfaults.
|
||||
# See https://github.com/python/cpython/issues/92311
|
||||
@jump_test(3, 1, [])
|
||||
@jump_test(3, 1, [], warning=(RuntimeWarning, unbound_locals))
|
||||
def test_jump_backward_over_listcomp(output):
|
||||
a = 1
|
||||
x = [i for i in range(10)]
|
||||
c = 3
|
||||
|
||||
@jump_test(8, 2, [2, 7, 2])
|
||||
@jump_test(8, 2, [2, 7, 2], warning=(RuntimeWarning, unbound_locals))
|
||||
def test_jump_backward_over_listcomp_v2(output):
|
||||
flag = False
|
||||
output.append(2)
|
||||
|
@ -2739,19 +2749,19 @@ output.append(4)
|
|||
output.append(7)
|
||||
output.append(8)
|
||||
|
||||
@async_jump_test(2, 3, [1, 3])
|
||||
@async_jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals))
|
||||
async def test_jump_forward_over_async_listcomp(output):
|
||||
output.append(1)
|
||||
x = [i async for i in asynciter(range(10))]
|
||||
output.append(3)
|
||||
|
||||
@async_jump_test(3, 1, [])
|
||||
@async_jump_test(3, 1, [], warning=(RuntimeWarning, unbound_locals))
|
||||
async def test_jump_backward_over_async_listcomp(output):
|
||||
a = 1
|
||||
x = [i async for i in asynciter(range(10))]
|
||||
c = 3
|
||||
|
||||
@async_jump_test(8, 2, [2, 7, 2])
|
||||
@async_jump_test(8, 2, [2, 7, 2], warning=(RuntimeWarning, unbound_locals))
|
||||
async def test_jump_backward_over_async_listcomp_v2(output):
|
||||
flag = False
|
||||
output.append(2)
|
||||
|
@ -2820,13 +2830,13 @@ output.append(4)
|
|||
)
|
||||
output.append(15)
|
||||
|
||||
@jump_test(2, 3, [1, 3])
|
||||
@jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals))
|
||||
def test_jump_extended_args_unpack_ex_simple(output):
|
||||
output.append(1)
|
||||
_, *_, _ = output.append(2) or "Spam"
|
||||
output.append(3)
|
||||
|
||||
@jump_test(3, 4, [1, 4, 4, 5])
|
||||
@jump_test(3, 4, [1, 4, 4, 5], warning=(RuntimeWarning, unbound_locals))
|
||||
def test_jump_extended_args_unpack_ex_tricky(output):
|
||||
output.append(1)
|
||||
(
|
||||
|
@ -2848,9 +2858,9 @@ output.append(4)
|
|||
namespace = {}
|
||||
exec("\n".join(source), namespace)
|
||||
f = namespace["f"]
|
||||
self.run_test(f, 2, 100_000, [1, 100_000])
|
||||
self.run_test(f, 2, 100_000, [1, 100_000], warning=(RuntimeWarning, self.unbound_locals))
|
||||
|
||||
@jump_test(2, 3, [1, 3])
|
||||
@jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals))
|
||||
def test_jump_or_pop(output):
|
||||
output.append(1)
|
||||
_ = output.append(2) and "Spam"
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Suppress and assert expected RuntimeWarnings in test_sys_settrace.py
|
Loading…
Reference in New Issue