17db96d56Sopenharmony_ci# Testing the line trace facility. 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_cifrom test import support 47db96d56Sopenharmony_ciimport unittest 57db96d56Sopenharmony_cifrom unittest.mock import MagicMock 67db96d56Sopenharmony_ciimport sys 77db96d56Sopenharmony_ciimport difflib 87db96d56Sopenharmony_ciimport gc 97db96d56Sopenharmony_cifrom functools import wraps 107db96d56Sopenharmony_ciimport asyncio 117db96d56Sopenharmony_cifrom test.support import import_helper 127db96d56Sopenharmony_ci 137db96d56Sopenharmony_cisupport.requires_working_socket(module=True) 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ciclass tracecontext: 167db96d56Sopenharmony_ci """Context manager that traces its enter and exit.""" 177db96d56Sopenharmony_ci def __init__(self, output, value): 187db96d56Sopenharmony_ci self.output = output 197db96d56Sopenharmony_ci self.value = value 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci def __enter__(self): 227db96d56Sopenharmony_ci self.output.append(self.value) 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_ci def __exit__(self, *exc_info): 257db96d56Sopenharmony_ci self.output.append(-self.value) 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ciclass asynctracecontext: 287db96d56Sopenharmony_ci """Asynchronous context manager that traces its aenter and aexit.""" 297db96d56Sopenharmony_ci def __init__(self, output, value): 307db96d56Sopenharmony_ci self.output = output 317db96d56Sopenharmony_ci self.value = value 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ci async def __aenter__(self): 347db96d56Sopenharmony_ci self.output.append(self.value) 357db96d56Sopenharmony_ci 367db96d56Sopenharmony_ci async def __aexit__(self, *exc_info): 377db96d56Sopenharmony_ci self.output.append(-self.value) 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ciasync def asynciter(iterable): 407db96d56Sopenharmony_ci """Convert an iterable to an asynchronous iterator.""" 417db96d56Sopenharmony_ci for x in iterable: 427db96d56Sopenharmony_ci yield x 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_ci 457db96d56Sopenharmony_ci# A very basic example. If this fails, we're in deep trouble. 467db96d56Sopenharmony_cidef basic(): 477db96d56Sopenharmony_ci return 1 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_cibasic.events = [(0, 'call'), 507db96d56Sopenharmony_ci (1, 'line'), 517db96d56Sopenharmony_ci (1, 'return')] 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_ci# Many of the tests below are tricky because they involve pass statements. 547db96d56Sopenharmony_ci# If there is implicit control flow around a pass statement (in an except 557db96d56Sopenharmony_ci# clause or else clause) under what conditions do you set a line number 567db96d56Sopenharmony_ci# following that clause? 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_ci# Some constructs like "while 0:", "if 0:" or "if 1:...else:..." could be optimized 607db96d56Sopenharmony_ci# away. Make sure that those lines aren't skipped. 617db96d56Sopenharmony_cidef arigo_example0(): 627db96d56Sopenharmony_ci x = 1 637db96d56Sopenharmony_ci del x 647db96d56Sopenharmony_ci while 0: 657db96d56Sopenharmony_ci pass 667db96d56Sopenharmony_ci x = 1 677db96d56Sopenharmony_ci 687db96d56Sopenharmony_ciarigo_example0.events = [(0, 'call'), 697db96d56Sopenharmony_ci (1, 'line'), 707db96d56Sopenharmony_ci (2, 'line'), 717db96d56Sopenharmony_ci (3, 'line'), 727db96d56Sopenharmony_ci (5, 'line'), 737db96d56Sopenharmony_ci (5, 'return')] 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_cidef arigo_example1(): 767db96d56Sopenharmony_ci x = 1 777db96d56Sopenharmony_ci del x 787db96d56Sopenharmony_ci if 0: 797db96d56Sopenharmony_ci pass 807db96d56Sopenharmony_ci x = 1 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ciarigo_example1.events = [(0, 'call'), 837db96d56Sopenharmony_ci (1, 'line'), 847db96d56Sopenharmony_ci (2, 'line'), 857db96d56Sopenharmony_ci (3, 'line'), 867db96d56Sopenharmony_ci (5, 'line'), 877db96d56Sopenharmony_ci (5, 'return')] 887db96d56Sopenharmony_ci 897db96d56Sopenharmony_cidef arigo_example2(): 907db96d56Sopenharmony_ci x = 1 917db96d56Sopenharmony_ci del x 927db96d56Sopenharmony_ci if 1: 937db96d56Sopenharmony_ci x = 1 947db96d56Sopenharmony_ci else: 957db96d56Sopenharmony_ci pass 967db96d56Sopenharmony_ci return None 977db96d56Sopenharmony_ci 987db96d56Sopenharmony_ciarigo_example2.events = [(0, 'call'), 997db96d56Sopenharmony_ci (1, 'line'), 1007db96d56Sopenharmony_ci (2, 'line'), 1017db96d56Sopenharmony_ci (3, 'line'), 1027db96d56Sopenharmony_ci (4, 'line'), 1037db96d56Sopenharmony_ci (7, 'line'), 1047db96d56Sopenharmony_ci (7, 'return')] 1057db96d56Sopenharmony_ci 1067db96d56Sopenharmony_ci 1077db96d56Sopenharmony_ci# check that lines consisting of just one instruction get traced: 1087db96d56Sopenharmony_cidef one_instr_line(): 1097db96d56Sopenharmony_ci x = 1 1107db96d56Sopenharmony_ci del x 1117db96d56Sopenharmony_ci x = 1 1127db96d56Sopenharmony_ci 1137db96d56Sopenharmony_cione_instr_line.events = [(0, 'call'), 1147db96d56Sopenharmony_ci (1, 'line'), 1157db96d56Sopenharmony_ci (2, 'line'), 1167db96d56Sopenharmony_ci (3, 'line'), 1177db96d56Sopenharmony_ci (3, 'return')] 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_cidef no_pop_tops(): # 0 1207db96d56Sopenharmony_ci x = 1 # 1 1217db96d56Sopenharmony_ci for a in range(2): # 2 1227db96d56Sopenharmony_ci if a: # 3 1237db96d56Sopenharmony_ci x = 1 # 4 1247db96d56Sopenharmony_ci else: # 5 1257db96d56Sopenharmony_ci x = 1 # 6 1267db96d56Sopenharmony_ci 1277db96d56Sopenharmony_cino_pop_tops.events = [(0, 'call'), 1287db96d56Sopenharmony_ci (1, 'line'), 1297db96d56Sopenharmony_ci (2, 'line'), 1307db96d56Sopenharmony_ci (3, 'line'), 1317db96d56Sopenharmony_ci (6, 'line'), 1327db96d56Sopenharmony_ci (2, 'line'), 1337db96d56Sopenharmony_ci (3, 'line'), 1347db96d56Sopenharmony_ci (4, 'line'), 1357db96d56Sopenharmony_ci (2, 'line'), 1367db96d56Sopenharmony_ci (2, 'return')] 1377db96d56Sopenharmony_ci 1387db96d56Sopenharmony_cidef no_pop_blocks(): 1397db96d56Sopenharmony_ci y = 1 1407db96d56Sopenharmony_ci while not y: 1417db96d56Sopenharmony_ci bla 1427db96d56Sopenharmony_ci x = 1 1437db96d56Sopenharmony_ci 1447db96d56Sopenharmony_cino_pop_blocks.events = [(0, 'call'), 1457db96d56Sopenharmony_ci (1, 'line'), 1467db96d56Sopenharmony_ci (2, 'line'), 1477db96d56Sopenharmony_ci (4, 'line'), 1487db96d56Sopenharmony_ci (4, 'return')] 1497db96d56Sopenharmony_ci 1507db96d56Sopenharmony_cidef called(): # line -3 1517db96d56Sopenharmony_ci x = 1 1527db96d56Sopenharmony_ci 1537db96d56Sopenharmony_cidef call(): # line 0 1547db96d56Sopenharmony_ci called() 1557db96d56Sopenharmony_ci 1567db96d56Sopenharmony_cicall.events = [(0, 'call'), 1577db96d56Sopenharmony_ci (1, 'line'), 1587db96d56Sopenharmony_ci (-3, 'call'), 1597db96d56Sopenharmony_ci (-2, 'line'), 1607db96d56Sopenharmony_ci (-2, 'return'), 1617db96d56Sopenharmony_ci (1, 'return')] 1627db96d56Sopenharmony_ci 1637db96d56Sopenharmony_cidef raises(): 1647db96d56Sopenharmony_ci raise Exception 1657db96d56Sopenharmony_ci 1667db96d56Sopenharmony_cidef test_raise(): 1677db96d56Sopenharmony_ci try: 1687db96d56Sopenharmony_ci raises() 1697db96d56Sopenharmony_ci except Exception: 1707db96d56Sopenharmony_ci pass 1717db96d56Sopenharmony_ci 1727db96d56Sopenharmony_citest_raise.events = [(0, 'call'), 1737db96d56Sopenharmony_ci (1, 'line'), 1747db96d56Sopenharmony_ci (2, 'line'), 1757db96d56Sopenharmony_ci (-3, 'call'), 1767db96d56Sopenharmony_ci (-2, 'line'), 1777db96d56Sopenharmony_ci (-2, 'exception'), 1787db96d56Sopenharmony_ci (-2, 'return'), 1797db96d56Sopenharmony_ci (2, 'exception'), 1807db96d56Sopenharmony_ci (3, 'line'), 1817db96d56Sopenharmony_ci (4, 'line'), 1827db96d56Sopenharmony_ci (4, 'return')] 1837db96d56Sopenharmony_ci 1847db96d56Sopenharmony_cidef _settrace_and_return(tracefunc): 1857db96d56Sopenharmony_ci sys.settrace(tracefunc) 1867db96d56Sopenharmony_ci sys._getframe().f_back.f_trace = tracefunc 1877db96d56Sopenharmony_cidef settrace_and_return(tracefunc): 1887db96d56Sopenharmony_ci _settrace_and_return(tracefunc) 1897db96d56Sopenharmony_ci 1907db96d56Sopenharmony_cisettrace_and_return.events = [(1, 'return')] 1917db96d56Sopenharmony_ci 1927db96d56Sopenharmony_cidef _settrace_and_raise(tracefunc): 1937db96d56Sopenharmony_ci sys.settrace(tracefunc) 1947db96d56Sopenharmony_ci sys._getframe().f_back.f_trace = tracefunc 1957db96d56Sopenharmony_ci raise RuntimeError 1967db96d56Sopenharmony_cidef settrace_and_raise(tracefunc): 1977db96d56Sopenharmony_ci try: 1987db96d56Sopenharmony_ci _settrace_and_raise(tracefunc) 1997db96d56Sopenharmony_ci except RuntimeError: 2007db96d56Sopenharmony_ci pass 2017db96d56Sopenharmony_ci 2027db96d56Sopenharmony_cisettrace_and_raise.events = [(2, 'exception'), 2037db96d56Sopenharmony_ci (3, 'line'), 2047db96d56Sopenharmony_ci (4, 'line'), 2057db96d56Sopenharmony_ci (4, 'return')] 2067db96d56Sopenharmony_ci 2077db96d56Sopenharmony_ci# implicit return example 2087db96d56Sopenharmony_ci# This test is interesting because of the else: pass 2097db96d56Sopenharmony_ci# part of the code. The code generate for the true 2107db96d56Sopenharmony_ci# part of the if contains a jump past the else branch. 2117db96d56Sopenharmony_ci# The compiler then generates an implicit "return None" 2127db96d56Sopenharmony_ci# Internally, the compiler visits the pass statement 2137db96d56Sopenharmony_ci# and stores its line number for use on the next instruction. 2147db96d56Sopenharmony_ci# The next instruction is the implicit return None. 2157db96d56Sopenharmony_cidef ireturn_example(): 2167db96d56Sopenharmony_ci a = 5 2177db96d56Sopenharmony_ci b = 5 2187db96d56Sopenharmony_ci if a == b: 2197db96d56Sopenharmony_ci b = a+1 2207db96d56Sopenharmony_ci else: 2217db96d56Sopenharmony_ci pass 2227db96d56Sopenharmony_ci 2237db96d56Sopenharmony_ciireturn_example.events = [(0, 'call'), 2247db96d56Sopenharmony_ci (1, 'line'), 2257db96d56Sopenharmony_ci (2, 'line'), 2267db96d56Sopenharmony_ci (3, 'line'), 2277db96d56Sopenharmony_ci (4, 'line'), 2287db96d56Sopenharmony_ci (4, 'return')] 2297db96d56Sopenharmony_ci 2307db96d56Sopenharmony_ci# Tight loop with while(1) example (SF #765624) 2317db96d56Sopenharmony_cidef tightloop_example(): 2327db96d56Sopenharmony_ci items = range(0, 3) 2337db96d56Sopenharmony_ci try: 2347db96d56Sopenharmony_ci i = 0 2357db96d56Sopenharmony_ci while 1: 2367db96d56Sopenharmony_ci b = items[i]; i+=1 2377db96d56Sopenharmony_ci except IndexError: 2387db96d56Sopenharmony_ci pass 2397db96d56Sopenharmony_ci 2407db96d56Sopenharmony_citightloop_example.events = [(0, 'call'), 2417db96d56Sopenharmony_ci (1, 'line'), 2427db96d56Sopenharmony_ci (2, 'line'), 2437db96d56Sopenharmony_ci (3, 'line'), 2447db96d56Sopenharmony_ci (4, 'line'), 2457db96d56Sopenharmony_ci (5, 'line'), 2467db96d56Sopenharmony_ci (4, 'line'), 2477db96d56Sopenharmony_ci (5, 'line'), 2487db96d56Sopenharmony_ci (4, 'line'), 2497db96d56Sopenharmony_ci (5, 'line'), 2507db96d56Sopenharmony_ci (4, 'line'), 2517db96d56Sopenharmony_ci (5, 'line'), 2527db96d56Sopenharmony_ci (5, 'exception'), 2537db96d56Sopenharmony_ci (6, 'line'), 2547db96d56Sopenharmony_ci (7, 'line'), 2557db96d56Sopenharmony_ci (7, 'return')] 2567db96d56Sopenharmony_ci 2577db96d56Sopenharmony_cidef tighterloop_example(): 2587db96d56Sopenharmony_ci items = range(1, 4) 2597db96d56Sopenharmony_ci try: 2607db96d56Sopenharmony_ci i = 0 2617db96d56Sopenharmony_ci while 1: i = items[i] 2627db96d56Sopenharmony_ci except IndexError: 2637db96d56Sopenharmony_ci pass 2647db96d56Sopenharmony_ci 2657db96d56Sopenharmony_citighterloop_example.events = [(0, 'call'), 2667db96d56Sopenharmony_ci (1, 'line'), 2677db96d56Sopenharmony_ci (2, 'line'), 2687db96d56Sopenharmony_ci (3, 'line'), 2697db96d56Sopenharmony_ci (4, 'line'), 2707db96d56Sopenharmony_ci (4, 'line'), 2717db96d56Sopenharmony_ci (4, 'line'), 2727db96d56Sopenharmony_ci (4, 'line'), 2737db96d56Sopenharmony_ci (4, 'exception'), 2747db96d56Sopenharmony_ci (5, 'line'), 2757db96d56Sopenharmony_ci (6, 'line'), 2767db96d56Sopenharmony_ci (6, 'return')] 2777db96d56Sopenharmony_ci 2787db96d56Sopenharmony_cidef generator_function(): 2797db96d56Sopenharmony_ci try: 2807db96d56Sopenharmony_ci yield True 2817db96d56Sopenharmony_ci "continued" 2827db96d56Sopenharmony_ci finally: 2837db96d56Sopenharmony_ci "finally" 2847db96d56Sopenharmony_cidef generator_example(): 2857db96d56Sopenharmony_ci # any() will leave the generator before its end 2867db96d56Sopenharmony_ci x = any(generator_function()) 2877db96d56Sopenharmony_ci 2887db96d56Sopenharmony_ci # the following lines were not traced 2897db96d56Sopenharmony_ci for x in range(10): 2907db96d56Sopenharmony_ci y = x 2917db96d56Sopenharmony_ci 2927db96d56Sopenharmony_cigenerator_example.events = ([(0, 'call'), 2937db96d56Sopenharmony_ci (2, 'line'), 2947db96d56Sopenharmony_ci (-6, 'call'), 2957db96d56Sopenharmony_ci (-5, 'line'), 2967db96d56Sopenharmony_ci (-4, 'line'), 2977db96d56Sopenharmony_ci (-4, 'return'), 2987db96d56Sopenharmony_ci (-4, 'call'), 2997db96d56Sopenharmony_ci (-4, 'exception'), 3007db96d56Sopenharmony_ci (-1, 'line'), 3017db96d56Sopenharmony_ci (-1, 'return')] + 3027db96d56Sopenharmony_ci [(5, 'line'), (6, 'line')] * 10 + 3037db96d56Sopenharmony_ci [(5, 'line'), (5, 'return')]) 3047db96d56Sopenharmony_ci 3057db96d56Sopenharmony_ci 3067db96d56Sopenharmony_ciclass Tracer: 3077db96d56Sopenharmony_ci def __init__(self, trace_line_events=None, trace_opcode_events=None): 3087db96d56Sopenharmony_ci self.trace_line_events = trace_line_events 3097db96d56Sopenharmony_ci self.trace_opcode_events = trace_opcode_events 3107db96d56Sopenharmony_ci self.events = [] 3117db96d56Sopenharmony_ci 3127db96d56Sopenharmony_ci def _reconfigure_frame(self, frame): 3137db96d56Sopenharmony_ci if self.trace_line_events is not None: 3147db96d56Sopenharmony_ci frame.f_trace_lines = self.trace_line_events 3157db96d56Sopenharmony_ci if self.trace_opcode_events is not None: 3167db96d56Sopenharmony_ci frame.f_trace_opcodes = self.trace_opcode_events 3177db96d56Sopenharmony_ci 3187db96d56Sopenharmony_ci def trace(self, frame, event, arg): 3197db96d56Sopenharmony_ci self._reconfigure_frame(frame) 3207db96d56Sopenharmony_ci self.events.append((frame.f_lineno, event)) 3217db96d56Sopenharmony_ci return self.trace 3227db96d56Sopenharmony_ci 3237db96d56Sopenharmony_ci def traceWithGenexp(self, frame, event, arg): 3247db96d56Sopenharmony_ci self._reconfigure_frame(frame) 3257db96d56Sopenharmony_ci (o for o in [1]) 3267db96d56Sopenharmony_ci self.events.append((frame.f_lineno, event)) 3277db96d56Sopenharmony_ci return self.trace 3287db96d56Sopenharmony_ci 3297db96d56Sopenharmony_ci 3307db96d56Sopenharmony_ciclass TraceTestCase(unittest.TestCase): 3317db96d56Sopenharmony_ci 3327db96d56Sopenharmony_ci # Disable gc collection when tracing, otherwise the 3337db96d56Sopenharmony_ci # deallocators may be traced as well. 3347db96d56Sopenharmony_ci def setUp(self): 3357db96d56Sopenharmony_ci self.using_gc = gc.isenabled() 3367db96d56Sopenharmony_ci gc.disable() 3377db96d56Sopenharmony_ci self.addCleanup(sys.settrace, sys.gettrace()) 3387db96d56Sopenharmony_ci 3397db96d56Sopenharmony_ci def tearDown(self): 3407db96d56Sopenharmony_ci if self.using_gc: 3417db96d56Sopenharmony_ci gc.enable() 3427db96d56Sopenharmony_ci 3437db96d56Sopenharmony_ci @staticmethod 3447db96d56Sopenharmony_ci def make_tracer(): 3457db96d56Sopenharmony_ci """Helper to allow test subclasses to configure tracers differently""" 3467db96d56Sopenharmony_ci return Tracer() 3477db96d56Sopenharmony_ci 3487db96d56Sopenharmony_ci def compare_events(self, line_offset, events, expected_events): 3497db96d56Sopenharmony_ci events = [(l - line_offset, e) for (l, e) in events] 3507db96d56Sopenharmony_ci if events != expected_events: 3517db96d56Sopenharmony_ci self.fail( 3527db96d56Sopenharmony_ci "events did not match expectation:\n" + 3537db96d56Sopenharmony_ci "\n".join(difflib.ndiff([str(x) for x in expected_events], 3547db96d56Sopenharmony_ci [str(x) for x in events]))) 3557db96d56Sopenharmony_ci 3567db96d56Sopenharmony_ci def run_and_compare(self, func, events): 3577db96d56Sopenharmony_ci tracer = self.make_tracer() 3587db96d56Sopenharmony_ci sys.settrace(tracer.trace) 3597db96d56Sopenharmony_ci func() 3607db96d56Sopenharmony_ci sys.settrace(None) 3617db96d56Sopenharmony_ci self.compare_events(func.__code__.co_firstlineno, 3627db96d56Sopenharmony_ci tracer.events, events) 3637db96d56Sopenharmony_ci 3647db96d56Sopenharmony_ci def run_test(self, func): 3657db96d56Sopenharmony_ci self.run_and_compare(func, func.events) 3667db96d56Sopenharmony_ci 3677db96d56Sopenharmony_ci def run_test2(self, func): 3687db96d56Sopenharmony_ci tracer = self.make_tracer() 3697db96d56Sopenharmony_ci func(tracer.trace) 3707db96d56Sopenharmony_ci sys.settrace(None) 3717db96d56Sopenharmony_ci self.compare_events(func.__code__.co_firstlineno, 3727db96d56Sopenharmony_ci tracer.events, func.events) 3737db96d56Sopenharmony_ci 3747db96d56Sopenharmony_ci def test_set_and_retrieve_none(self): 3757db96d56Sopenharmony_ci sys.settrace(None) 3767db96d56Sopenharmony_ci assert sys.gettrace() is None 3777db96d56Sopenharmony_ci 3787db96d56Sopenharmony_ci def test_set_and_retrieve_func(self): 3797db96d56Sopenharmony_ci def fn(*args): 3807db96d56Sopenharmony_ci pass 3817db96d56Sopenharmony_ci 3827db96d56Sopenharmony_ci sys.settrace(fn) 3837db96d56Sopenharmony_ci try: 3847db96d56Sopenharmony_ci assert sys.gettrace() is fn 3857db96d56Sopenharmony_ci finally: 3867db96d56Sopenharmony_ci sys.settrace(None) 3877db96d56Sopenharmony_ci 3887db96d56Sopenharmony_ci def test_01_basic(self): 3897db96d56Sopenharmony_ci self.run_test(basic) 3907db96d56Sopenharmony_ci def test_02_arigo0(self): 3917db96d56Sopenharmony_ci self.run_test(arigo_example0) 3927db96d56Sopenharmony_ci def test_02_arigo1(self): 3937db96d56Sopenharmony_ci self.run_test(arigo_example1) 3947db96d56Sopenharmony_ci def test_02_arigo2(self): 3957db96d56Sopenharmony_ci self.run_test(arigo_example2) 3967db96d56Sopenharmony_ci def test_03_one_instr(self): 3977db96d56Sopenharmony_ci self.run_test(one_instr_line) 3987db96d56Sopenharmony_ci def test_04_no_pop_blocks(self): 3997db96d56Sopenharmony_ci self.run_test(no_pop_blocks) 4007db96d56Sopenharmony_ci def test_05_no_pop_tops(self): 4017db96d56Sopenharmony_ci self.run_test(no_pop_tops) 4027db96d56Sopenharmony_ci def test_06_call(self): 4037db96d56Sopenharmony_ci self.run_test(call) 4047db96d56Sopenharmony_ci def test_07_raise(self): 4057db96d56Sopenharmony_ci self.run_test(test_raise) 4067db96d56Sopenharmony_ci 4077db96d56Sopenharmony_ci def test_08_settrace_and_return(self): 4087db96d56Sopenharmony_ci self.run_test2(settrace_and_return) 4097db96d56Sopenharmony_ci def test_09_settrace_and_raise(self): 4107db96d56Sopenharmony_ci self.run_test2(settrace_and_raise) 4117db96d56Sopenharmony_ci def test_10_ireturn(self): 4127db96d56Sopenharmony_ci self.run_test(ireturn_example) 4137db96d56Sopenharmony_ci def test_11_tightloop(self): 4147db96d56Sopenharmony_ci self.run_test(tightloop_example) 4157db96d56Sopenharmony_ci def test_12_tighterloop(self): 4167db96d56Sopenharmony_ci self.run_test(tighterloop_example) 4177db96d56Sopenharmony_ci 4187db96d56Sopenharmony_ci def test_13_genexp(self): 4197db96d56Sopenharmony_ci self.run_test(generator_example) 4207db96d56Sopenharmony_ci # issue1265: if the trace function contains a generator, 4217db96d56Sopenharmony_ci # and if the traced function contains another generator 4227db96d56Sopenharmony_ci # that is not completely exhausted, the trace stopped. 4237db96d56Sopenharmony_ci # Worse: the 'finally' clause was not invoked. 4247db96d56Sopenharmony_ci tracer = self.make_tracer() 4257db96d56Sopenharmony_ci sys.settrace(tracer.traceWithGenexp) 4267db96d56Sopenharmony_ci generator_example() 4277db96d56Sopenharmony_ci sys.settrace(None) 4287db96d56Sopenharmony_ci self.compare_events(generator_example.__code__.co_firstlineno, 4297db96d56Sopenharmony_ci tracer.events, generator_example.events) 4307db96d56Sopenharmony_ci 4317db96d56Sopenharmony_ci def test_14_onliner_if(self): 4327db96d56Sopenharmony_ci def onliners(): 4337db96d56Sopenharmony_ci if True: x=False 4347db96d56Sopenharmony_ci else: x=True 4357db96d56Sopenharmony_ci return 0 4367db96d56Sopenharmony_ci self.run_and_compare( 4377db96d56Sopenharmony_ci onliners, 4387db96d56Sopenharmony_ci [(0, 'call'), 4397db96d56Sopenharmony_ci (1, 'line'), 4407db96d56Sopenharmony_ci (3, 'line'), 4417db96d56Sopenharmony_ci (3, 'return')]) 4427db96d56Sopenharmony_ci 4437db96d56Sopenharmony_ci def test_15_loops(self): 4447db96d56Sopenharmony_ci # issue1750076: "while" expression is skipped by debugger 4457db96d56Sopenharmony_ci def for_example(): 4467db96d56Sopenharmony_ci for x in range(2): 4477db96d56Sopenharmony_ci pass 4487db96d56Sopenharmony_ci self.run_and_compare( 4497db96d56Sopenharmony_ci for_example, 4507db96d56Sopenharmony_ci [(0, 'call'), 4517db96d56Sopenharmony_ci (1, 'line'), 4527db96d56Sopenharmony_ci (2, 'line'), 4537db96d56Sopenharmony_ci (1, 'line'), 4547db96d56Sopenharmony_ci (2, 'line'), 4557db96d56Sopenharmony_ci (1, 'line'), 4567db96d56Sopenharmony_ci (1, 'return')]) 4577db96d56Sopenharmony_ci 4587db96d56Sopenharmony_ci def while_example(): 4597db96d56Sopenharmony_ci # While expression should be traced on every loop 4607db96d56Sopenharmony_ci x = 2 4617db96d56Sopenharmony_ci while x > 0: 4627db96d56Sopenharmony_ci x -= 1 4637db96d56Sopenharmony_ci self.run_and_compare( 4647db96d56Sopenharmony_ci while_example, 4657db96d56Sopenharmony_ci [(0, 'call'), 4667db96d56Sopenharmony_ci (2, 'line'), 4677db96d56Sopenharmony_ci (3, 'line'), 4687db96d56Sopenharmony_ci (4, 'line'), 4697db96d56Sopenharmony_ci (3, 'line'), 4707db96d56Sopenharmony_ci (4, 'line'), 4717db96d56Sopenharmony_ci (3, 'line'), 4727db96d56Sopenharmony_ci (3, 'return')]) 4737db96d56Sopenharmony_ci 4747db96d56Sopenharmony_ci def test_16_blank_lines(self): 4757db96d56Sopenharmony_ci namespace = {} 4767db96d56Sopenharmony_ci exec("def f():\n" + "\n" * 256 + " pass", namespace) 4777db96d56Sopenharmony_ci self.run_and_compare( 4787db96d56Sopenharmony_ci namespace["f"], 4797db96d56Sopenharmony_ci [(0, 'call'), 4807db96d56Sopenharmony_ci (257, 'line'), 4817db96d56Sopenharmony_ci (257, 'return')]) 4827db96d56Sopenharmony_ci 4837db96d56Sopenharmony_ci def test_17_none_f_trace(self): 4847db96d56Sopenharmony_ci # Issue 20041: fix TypeError when f_trace is set to None. 4857db96d56Sopenharmony_ci def func(): 4867db96d56Sopenharmony_ci sys._getframe().f_trace = None 4877db96d56Sopenharmony_ci lineno = 2 4887db96d56Sopenharmony_ci self.run_and_compare(func, 4897db96d56Sopenharmony_ci [(0, 'call'), 4907db96d56Sopenharmony_ci (1, 'line')]) 4917db96d56Sopenharmony_ci 4927db96d56Sopenharmony_ci def test_18_except_with_name(self): 4937db96d56Sopenharmony_ci def func(): 4947db96d56Sopenharmony_ci try: 4957db96d56Sopenharmony_ci try: 4967db96d56Sopenharmony_ci raise Exception 4977db96d56Sopenharmony_ci except Exception as e: 4987db96d56Sopenharmony_ci raise 4997db96d56Sopenharmony_ci x = "Something" 5007db96d56Sopenharmony_ci y = "Something" 5017db96d56Sopenharmony_ci except Exception: 5027db96d56Sopenharmony_ci pass 5037db96d56Sopenharmony_ci 5047db96d56Sopenharmony_ci self.run_and_compare(func, 5057db96d56Sopenharmony_ci [(0, 'call'), 5067db96d56Sopenharmony_ci (1, 'line'), 5077db96d56Sopenharmony_ci (2, 'line'), 5087db96d56Sopenharmony_ci (3, 'line'), 5097db96d56Sopenharmony_ci (3, 'exception'), 5107db96d56Sopenharmony_ci (4, 'line'), 5117db96d56Sopenharmony_ci (5, 'line'), 5127db96d56Sopenharmony_ci (8, 'line'), 5137db96d56Sopenharmony_ci (9, 'line'), 5147db96d56Sopenharmony_ci (9, 'return')]) 5157db96d56Sopenharmony_ci 5167db96d56Sopenharmony_ci def test_19_except_with_finally(self): 5177db96d56Sopenharmony_ci def func(): 5187db96d56Sopenharmony_ci try: 5197db96d56Sopenharmony_ci try: 5207db96d56Sopenharmony_ci raise Exception 5217db96d56Sopenharmony_ci finally: 5227db96d56Sopenharmony_ci y = "Something" 5237db96d56Sopenharmony_ci except Exception: 5247db96d56Sopenharmony_ci b = 23 5257db96d56Sopenharmony_ci 5267db96d56Sopenharmony_ci self.run_and_compare(func, 5277db96d56Sopenharmony_ci [(0, 'call'), 5287db96d56Sopenharmony_ci (1, 'line'), 5297db96d56Sopenharmony_ci (2, 'line'), 5307db96d56Sopenharmony_ci (3, 'line'), 5317db96d56Sopenharmony_ci (3, 'exception'), 5327db96d56Sopenharmony_ci (5, 'line'), 5337db96d56Sopenharmony_ci (6, 'line'), 5347db96d56Sopenharmony_ci (7, 'line'), 5357db96d56Sopenharmony_ci (7, 'return')]) 5367db96d56Sopenharmony_ci 5377db96d56Sopenharmony_ci def test_20_async_for_loop(self): 5387db96d56Sopenharmony_ci class AsyncIteratorWrapper: 5397db96d56Sopenharmony_ci def __init__(self, obj): 5407db96d56Sopenharmony_ci self._it = iter(obj) 5417db96d56Sopenharmony_ci 5427db96d56Sopenharmony_ci def __aiter__(self): 5437db96d56Sopenharmony_ci return self 5447db96d56Sopenharmony_ci 5457db96d56Sopenharmony_ci async def __anext__(self): 5467db96d56Sopenharmony_ci try: 5477db96d56Sopenharmony_ci return next(self._it) 5487db96d56Sopenharmony_ci except StopIteration: 5497db96d56Sopenharmony_ci raise StopAsyncIteration 5507db96d56Sopenharmony_ci 5517db96d56Sopenharmony_ci async def doit_async(): 5527db96d56Sopenharmony_ci async for letter in AsyncIteratorWrapper("abc"): 5537db96d56Sopenharmony_ci x = letter 5547db96d56Sopenharmony_ci y = 42 5557db96d56Sopenharmony_ci 5567db96d56Sopenharmony_ci def run(tracer): 5577db96d56Sopenharmony_ci x = doit_async() 5587db96d56Sopenharmony_ci try: 5597db96d56Sopenharmony_ci sys.settrace(tracer) 5607db96d56Sopenharmony_ci x.send(None) 5617db96d56Sopenharmony_ci finally: 5627db96d56Sopenharmony_ci sys.settrace(None) 5637db96d56Sopenharmony_ci 5647db96d56Sopenharmony_ci tracer = self.make_tracer() 5657db96d56Sopenharmony_ci events = [ 5667db96d56Sopenharmony_ci (0, 'call'), 5677db96d56Sopenharmony_ci (1, 'line'), 5687db96d56Sopenharmony_ci (-12, 'call'), 5697db96d56Sopenharmony_ci (-11, 'line'), 5707db96d56Sopenharmony_ci (-11, 'return'), 5717db96d56Sopenharmony_ci (-9, 'call'), 5727db96d56Sopenharmony_ci (-8, 'line'), 5737db96d56Sopenharmony_ci (-8, 'return'), 5747db96d56Sopenharmony_ci (-6, 'call'), 5757db96d56Sopenharmony_ci (-5, 'line'), 5767db96d56Sopenharmony_ci (-4, 'line'), 5777db96d56Sopenharmony_ci (-4, 'return'), 5787db96d56Sopenharmony_ci (1, 'exception'), 5797db96d56Sopenharmony_ci (2, 'line'), 5807db96d56Sopenharmony_ci (1, 'line'), 5817db96d56Sopenharmony_ci (-6, 'call'), 5827db96d56Sopenharmony_ci (-5, 'line'), 5837db96d56Sopenharmony_ci (-4, 'line'), 5847db96d56Sopenharmony_ci (-4, 'return'), 5857db96d56Sopenharmony_ci (1, 'exception'), 5867db96d56Sopenharmony_ci (2, 'line'), 5877db96d56Sopenharmony_ci (1, 'line'), 5887db96d56Sopenharmony_ci (-6, 'call'), 5897db96d56Sopenharmony_ci (-5, 'line'), 5907db96d56Sopenharmony_ci (-4, 'line'), 5917db96d56Sopenharmony_ci (-4, 'return'), 5927db96d56Sopenharmony_ci (1, 'exception'), 5937db96d56Sopenharmony_ci (2, 'line'), 5947db96d56Sopenharmony_ci (1, 'line'), 5957db96d56Sopenharmony_ci (-6, 'call'), 5967db96d56Sopenharmony_ci (-5, 'line'), 5977db96d56Sopenharmony_ci (-4, 'line'), 5987db96d56Sopenharmony_ci (-4, 'exception'), 5997db96d56Sopenharmony_ci (-3, 'line'), 6007db96d56Sopenharmony_ci (-2, 'line'), 6017db96d56Sopenharmony_ci (-2, 'exception'), 6027db96d56Sopenharmony_ci (-2, 'return'), 6037db96d56Sopenharmony_ci (1, 'exception'), 6047db96d56Sopenharmony_ci (3, 'line'), 6057db96d56Sopenharmony_ci (3, 'return')] 6067db96d56Sopenharmony_ci try: 6077db96d56Sopenharmony_ci run(tracer.trace) 6087db96d56Sopenharmony_ci except Exception: 6097db96d56Sopenharmony_ci pass 6107db96d56Sopenharmony_ci self.compare_events(doit_async.__code__.co_firstlineno, 6117db96d56Sopenharmony_ci tracer.events, events) 6127db96d56Sopenharmony_ci 6137db96d56Sopenharmony_ci def test_async_for_backwards_jump_has_no_line(self): 6147db96d56Sopenharmony_ci async def arange(n): 6157db96d56Sopenharmony_ci for i in range(n): 6167db96d56Sopenharmony_ci yield i 6177db96d56Sopenharmony_ci async def f(): 6187db96d56Sopenharmony_ci async for i in arange(3): 6197db96d56Sopenharmony_ci if i > 100: 6207db96d56Sopenharmony_ci break # should never be traced 6217db96d56Sopenharmony_ci 6227db96d56Sopenharmony_ci tracer = self.make_tracer() 6237db96d56Sopenharmony_ci coro = f() 6247db96d56Sopenharmony_ci try: 6257db96d56Sopenharmony_ci sys.settrace(tracer.trace) 6267db96d56Sopenharmony_ci coro.send(None) 6277db96d56Sopenharmony_ci except Exception: 6287db96d56Sopenharmony_ci pass 6297db96d56Sopenharmony_ci finally: 6307db96d56Sopenharmony_ci sys.settrace(None) 6317db96d56Sopenharmony_ci 6327db96d56Sopenharmony_ci events = [ 6337db96d56Sopenharmony_ci (0, 'call'), 6347db96d56Sopenharmony_ci (1, 'line'), 6357db96d56Sopenharmony_ci (-3, 'call'), 6367db96d56Sopenharmony_ci (-2, 'line'), 6377db96d56Sopenharmony_ci (-1, 'line'), 6387db96d56Sopenharmony_ci (-1, 'return'), 6397db96d56Sopenharmony_ci (1, 'exception'), 6407db96d56Sopenharmony_ci (2, 'line'), 6417db96d56Sopenharmony_ci (1, 'line'), 6427db96d56Sopenharmony_ci (-1, 'call'), 6437db96d56Sopenharmony_ci (-2, 'line'), 6447db96d56Sopenharmony_ci (-1, 'line'), 6457db96d56Sopenharmony_ci (-1, 'return'), 6467db96d56Sopenharmony_ci (1, 'exception'), 6477db96d56Sopenharmony_ci (2, 'line'), 6487db96d56Sopenharmony_ci (1, 'line'), 6497db96d56Sopenharmony_ci (-1, 'call'), 6507db96d56Sopenharmony_ci (-2, 'line'), 6517db96d56Sopenharmony_ci (-1, 'line'), 6527db96d56Sopenharmony_ci (-1, 'return'), 6537db96d56Sopenharmony_ci (1, 'exception'), 6547db96d56Sopenharmony_ci (2, 'line'), 6557db96d56Sopenharmony_ci (1, 'line'), 6567db96d56Sopenharmony_ci (-1, 'call'), 6577db96d56Sopenharmony_ci (-2, 'line'), 6587db96d56Sopenharmony_ci (-2, 'return'), 6597db96d56Sopenharmony_ci (1, 'exception'), 6607db96d56Sopenharmony_ci (1, 'return'), 6617db96d56Sopenharmony_ci ] 6627db96d56Sopenharmony_ci self.compare_events(f.__code__.co_firstlineno, 6637db96d56Sopenharmony_ci tracer.events, events) 6647db96d56Sopenharmony_ci 6657db96d56Sopenharmony_ci def test_21_repeated_pass(self): 6667db96d56Sopenharmony_ci def func(): 6677db96d56Sopenharmony_ci pass 6687db96d56Sopenharmony_ci pass 6697db96d56Sopenharmony_ci 6707db96d56Sopenharmony_ci self.run_and_compare(func, 6717db96d56Sopenharmony_ci [(0, 'call'), 6727db96d56Sopenharmony_ci (1, 'line'), 6737db96d56Sopenharmony_ci (2, 'line'), 6747db96d56Sopenharmony_ci (2, 'return')]) 6757db96d56Sopenharmony_ci 6767db96d56Sopenharmony_ci def test_loop_in_try_except(self): 6777db96d56Sopenharmony_ci # https://bugs.python.org/issue41670 6787db96d56Sopenharmony_ci 6797db96d56Sopenharmony_ci def func(): 6807db96d56Sopenharmony_ci try: 6817db96d56Sopenharmony_ci for i in []: pass 6827db96d56Sopenharmony_ci return 1 6837db96d56Sopenharmony_ci except: 6847db96d56Sopenharmony_ci return 2 6857db96d56Sopenharmony_ci 6867db96d56Sopenharmony_ci self.run_and_compare(func, 6877db96d56Sopenharmony_ci [(0, 'call'), 6887db96d56Sopenharmony_ci (1, 'line'), 6897db96d56Sopenharmony_ci (2, 'line'), 6907db96d56Sopenharmony_ci (3, 'line'), 6917db96d56Sopenharmony_ci (3, 'return')]) 6927db96d56Sopenharmony_ci 6937db96d56Sopenharmony_ci def test_try_except_no_exception(self): 6947db96d56Sopenharmony_ci 6957db96d56Sopenharmony_ci def func(): 6967db96d56Sopenharmony_ci try: 6977db96d56Sopenharmony_ci 2 6987db96d56Sopenharmony_ci except: 6997db96d56Sopenharmony_ci 4 7007db96d56Sopenharmony_ci else: 7017db96d56Sopenharmony_ci 6 7027db96d56Sopenharmony_ci if False: 7037db96d56Sopenharmony_ci 8 7047db96d56Sopenharmony_ci else: 7057db96d56Sopenharmony_ci 10 7067db96d56Sopenharmony_ci if func.__name__ == 'Fred': 7077db96d56Sopenharmony_ci 12 7087db96d56Sopenharmony_ci finally: 7097db96d56Sopenharmony_ci 14 7107db96d56Sopenharmony_ci 7117db96d56Sopenharmony_ci self.run_and_compare(func, 7127db96d56Sopenharmony_ci [(0, 'call'), 7137db96d56Sopenharmony_ci (1, 'line'), 7147db96d56Sopenharmony_ci (2, 'line'), 7157db96d56Sopenharmony_ci (6, 'line'), 7167db96d56Sopenharmony_ci (7, 'line'), 7177db96d56Sopenharmony_ci (10, 'line'), 7187db96d56Sopenharmony_ci (11, 'line'), 7197db96d56Sopenharmony_ci (14, 'line'), 7207db96d56Sopenharmony_ci (14, 'return')]) 7217db96d56Sopenharmony_ci 7227db96d56Sopenharmony_ci def test_try_exception_in_else(self): 7237db96d56Sopenharmony_ci 7247db96d56Sopenharmony_ci def func(): 7257db96d56Sopenharmony_ci try: 7267db96d56Sopenharmony_ci try: 7277db96d56Sopenharmony_ci 3 7287db96d56Sopenharmony_ci except: 7297db96d56Sopenharmony_ci 5 7307db96d56Sopenharmony_ci else: 7317db96d56Sopenharmony_ci 7 7327db96d56Sopenharmony_ci raise Exception 7337db96d56Sopenharmony_ci finally: 7347db96d56Sopenharmony_ci 10 7357db96d56Sopenharmony_ci except: 7367db96d56Sopenharmony_ci 12 7377db96d56Sopenharmony_ci finally: 7387db96d56Sopenharmony_ci 14 7397db96d56Sopenharmony_ci 7407db96d56Sopenharmony_ci self.run_and_compare(func, 7417db96d56Sopenharmony_ci [(0, 'call'), 7427db96d56Sopenharmony_ci (1, 'line'), 7437db96d56Sopenharmony_ci (2, 'line'), 7447db96d56Sopenharmony_ci (3, 'line'), 7457db96d56Sopenharmony_ci (7, 'line'), 7467db96d56Sopenharmony_ci (8, 'line'), 7477db96d56Sopenharmony_ci (8, 'exception'), 7487db96d56Sopenharmony_ci (10, 'line'), 7497db96d56Sopenharmony_ci (11, 'line'), 7507db96d56Sopenharmony_ci (12, 'line'), 7517db96d56Sopenharmony_ci (14, 'line'), 7527db96d56Sopenharmony_ci (14, 'return')]) 7537db96d56Sopenharmony_ci 7547db96d56Sopenharmony_ci def test_nested_loops(self): 7557db96d56Sopenharmony_ci 7567db96d56Sopenharmony_ci def func(): 7577db96d56Sopenharmony_ci for i in range(2): 7587db96d56Sopenharmony_ci for j in range(2): 7597db96d56Sopenharmony_ci a = i + j 7607db96d56Sopenharmony_ci return a == 1 7617db96d56Sopenharmony_ci 7627db96d56Sopenharmony_ci self.run_and_compare(func, 7637db96d56Sopenharmony_ci [(0, 'call'), 7647db96d56Sopenharmony_ci (1, 'line'), 7657db96d56Sopenharmony_ci (2, 'line'), 7667db96d56Sopenharmony_ci (3, 'line'), 7677db96d56Sopenharmony_ci (2, 'line'), 7687db96d56Sopenharmony_ci (3, 'line'), 7697db96d56Sopenharmony_ci (2, 'line'), 7707db96d56Sopenharmony_ci (1, 'line'), 7717db96d56Sopenharmony_ci (2, 'line'), 7727db96d56Sopenharmony_ci (3, 'line'), 7737db96d56Sopenharmony_ci (2, 'line'), 7747db96d56Sopenharmony_ci (3, 'line'), 7757db96d56Sopenharmony_ci (2, 'line'), 7767db96d56Sopenharmony_ci (1, 'line'), 7777db96d56Sopenharmony_ci (4, 'line'), 7787db96d56Sopenharmony_ci (4, 'return')]) 7797db96d56Sopenharmony_ci 7807db96d56Sopenharmony_ci def test_if_break(self): 7817db96d56Sopenharmony_ci 7827db96d56Sopenharmony_ci def func(): 7837db96d56Sopenharmony_ci seq = [1, 0] 7847db96d56Sopenharmony_ci while seq: 7857db96d56Sopenharmony_ci n = seq.pop() 7867db96d56Sopenharmony_ci if n: 7877db96d56Sopenharmony_ci break # line 5 7887db96d56Sopenharmony_ci else: 7897db96d56Sopenharmony_ci n = 99 7907db96d56Sopenharmony_ci return n # line 8 7917db96d56Sopenharmony_ci 7927db96d56Sopenharmony_ci self.run_and_compare(func, 7937db96d56Sopenharmony_ci [(0, 'call'), 7947db96d56Sopenharmony_ci (1, 'line'), 7957db96d56Sopenharmony_ci (2, 'line'), 7967db96d56Sopenharmony_ci (3, 'line'), 7977db96d56Sopenharmony_ci (4, 'line'), 7987db96d56Sopenharmony_ci (2, 'line'), 7997db96d56Sopenharmony_ci (3, 'line'), 8007db96d56Sopenharmony_ci (4, 'line'), 8017db96d56Sopenharmony_ci (5, 'line'), 8027db96d56Sopenharmony_ci (8, 'line'), 8037db96d56Sopenharmony_ci (8, 'return')]) 8047db96d56Sopenharmony_ci 8057db96d56Sopenharmony_ci def test_break_through_finally(self): 8067db96d56Sopenharmony_ci 8077db96d56Sopenharmony_ci def func(): 8087db96d56Sopenharmony_ci a, c, d, i = 1, 1, 1, 99 8097db96d56Sopenharmony_ci try: 8107db96d56Sopenharmony_ci for i in range(3): 8117db96d56Sopenharmony_ci try: 8127db96d56Sopenharmony_ci a = 5 8137db96d56Sopenharmony_ci if i > 0: 8147db96d56Sopenharmony_ci break # line 7 8157db96d56Sopenharmony_ci a = 8 8167db96d56Sopenharmony_ci finally: 8177db96d56Sopenharmony_ci c = 10 8187db96d56Sopenharmony_ci except: 8197db96d56Sopenharmony_ci d = 12 # line 12 8207db96d56Sopenharmony_ci assert a == 5 and c == 10 and d == 1 # line 13 8217db96d56Sopenharmony_ci 8227db96d56Sopenharmony_ci self.run_and_compare(func, 8237db96d56Sopenharmony_ci [(0, 'call'), 8247db96d56Sopenharmony_ci (1, 'line'), 8257db96d56Sopenharmony_ci (2, 'line'), 8267db96d56Sopenharmony_ci (3, 'line'), 8277db96d56Sopenharmony_ci (4, 'line'), 8287db96d56Sopenharmony_ci (5, 'line'), 8297db96d56Sopenharmony_ci (6, 'line'), 8307db96d56Sopenharmony_ci (8, 'line'), 8317db96d56Sopenharmony_ci (10, 'line'), 8327db96d56Sopenharmony_ci (3, 'line'), 8337db96d56Sopenharmony_ci (4, 'line'), 8347db96d56Sopenharmony_ci (5, 'line'), 8357db96d56Sopenharmony_ci (6, 'line'), 8367db96d56Sopenharmony_ci (7, 'line'), 8377db96d56Sopenharmony_ci (10, 'line'), 8387db96d56Sopenharmony_ci (13, 'line'), 8397db96d56Sopenharmony_ci (13, 'return')]) 8407db96d56Sopenharmony_ci 8417db96d56Sopenharmony_ci def test_continue_through_finally(self): 8427db96d56Sopenharmony_ci 8437db96d56Sopenharmony_ci def func(): 8447db96d56Sopenharmony_ci a, b, c, d, i = 1, 1, 1, 1, 99 8457db96d56Sopenharmony_ci try: 8467db96d56Sopenharmony_ci for i in range(2): 8477db96d56Sopenharmony_ci try: 8487db96d56Sopenharmony_ci a = 5 8497db96d56Sopenharmony_ci if i > 0: 8507db96d56Sopenharmony_ci continue # line 7 8517db96d56Sopenharmony_ci b = 8 8527db96d56Sopenharmony_ci finally: 8537db96d56Sopenharmony_ci c = 10 8547db96d56Sopenharmony_ci except: 8557db96d56Sopenharmony_ci d = 12 # line 12 8567db96d56Sopenharmony_ci assert (a, b, c, d) == (5, 8, 10, 1) # line 13 8577db96d56Sopenharmony_ci 8587db96d56Sopenharmony_ci self.run_and_compare(func, 8597db96d56Sopenharmony_ci [(0, 'call'), 8607db96d56Sopenharmony_ci (1, 'line'), 8617db96d56Sopenharmony_ci (2, 'line'), 8627db96d56Sopenharmony_ci (3, 'line'), 8637db96d56Sopenharmony_ci (4, 'line'), 8647db96d56Sopenharmony_ci (5, 'line'), 8657db96d56Sopenharmony_ci (6, 'line'), 8667db96d56Sopenharmony_ci (8, 'line'), 8677db96d56Sopenharmony_ci (10, 'line'), 8687db96d56Sopenharmony_ci (3, 'line'), 8697db96d56Sopenharmony_ci (4, 'line'), 8707db96d56Sopenharmony_ci (5, 'line'), 8717db96d56Sopenharmony_ci (6, 'line'), 8727db96d56Sopenharmony_ci (7, 'line'), 8737db96d56Sopenharmony_ci (10, 'line'), 8747db96d56Sopenharmony_ci (3, 'line'), 8757db96d56Sopenharmony_ci (13, 'line'), 8767db96d56Sopenharmony_ci (13, 'return')]) 8777db96d56Sopenharmony_ci 8787db96d56Sopenharmony_ci def test_return_through_finally(self): 8797db96d56Sopenharmony_ci 8807db96d56Sopenharmony_ci def func(): 8817db96d56Sopenharmony_ci try: 8827db96d56Sopenharmony_ci return 2 8837db96d56Sopenharmony_ci finally: 8847db96d56Sopenharmony_ci 4 8857db96d56Sopenharmony_ci 8867db96d56Sopenharmony_ci self.run_and_compare(func, 8877db96d56Sopenharmony_ci [(0, 'call'), 8887db96d56Sopenharmony_ci (1, 'line'), 8897db96d56Sopenharmony_ci (2, 'line'), 8907db96d56Sopenharmony_ci (4, 'line'), 8917db96d56Sopenharmony_ci (4, 'return')]) 8927db96d56Sopenharmony_ci 8937db96d56Sopenharmony_ci def test_try_except_with_wrong_type(self): 8947db96d56Sopenharmony_ci 8957db96d56Sopenharmony_ci def func(): 8967db96d56Sopenharmony_ci try: 8977db96d56Sopenharmony_ci 2/0 8987db96d56Sopenharmony_ci except IndexError: 8997db96d56Sopenharmony_ci 4 9007db96d56Sopenharmony_ci finally: 9017db96d56Sopenharmony_ci return 6 9027db96d56Sopenharmony_ci 9037db96d56Sopenharmony_ci self.run_and_compare(func, 9047db96d56Sopenharmony_ci [(0, 'call'), 9057db96d56Sopenharmony_ci (1, 'line'), 9067db96d56Sopenharmony_ci (2, 'line'), 9077db96d56Sopenharmony_ci (2, 'exception'), 9087db96d56Sopenharmony_ci (3, 'line'), 9097db96d56Sopenharmony_ci (6, 'line'), 9107db96d56Sopenharmony_ci (6, 'return')]) 9117db96d56Sopenharmony_ci 9127db96d56Sopenharmony_ci def test_break_to_continue1(self): 9137db96d56Sopenharmony_ci 9147db96d56Sopenharmony_ci def func(): 9157db96d56Sopenharmony_ci TRUE = 1 9167db96d56Sopenharmony_ci x = [1] 9177db96d56Sopenharmony_ci while x: 9187db96d56Sopenharmony_ci x.pop() 9197db96d56Sopenharmony_ci while TRUE: 9207db96d56Sopenharmony_ci break 9217db96d56Sopenharmony_ci continue 9227db96d56Sopenharmony_ci 9237db96d56Sopenharmony_ci self.run_and_compare(func, 9247db96d56Sopenharmony_ci [(0, 'call'), 9257db96d56Sopenharmony_ci (1, 'line'), 9267db96d56Sopenharmony_ci (2, 'line'), 9277db96d56Sopenharmony_ci (3, 'line'), 9287db96d56Sopenharmony_ci (4, 'line'), 9297db96d56Sopenharmony_ci (5, 'line'), 9307db96d56Sopenharmony_ci (6, 'line'), 9317db96d56Sopenharmony_ci (7, 'line'), 9327db96d56Sopenharmony_ci (3, 'line'), 9337db96d56Sopenharmony_ci (3, 'return')]) 9347db96d56Sopenharmony_ci 9357db96d56Sopenharmony_ci def test_break_to_continue2(self): 9367db96d56Sopenharmony_ci 9377db96d56Sopenharmony_ci def func(): 9387db96d56Sopenharmony_ci TRUE = 1 9397db96d56Sopenharmony_ci x = [1] 9407db96d56Sopenharmony_ci while x: 9417db96d56Sopenharmony_ci x.pop() 9427db96d56Sopenharmony_ci while TRUE: 9437db96d56Sopenharmony_ci break 9447db96d56Sopenharmony_ci else: 9457db96d56Sopenharmony_ci continue 9467db96d56Sopenharmony_ci 9477db96d56Sopenharmony_ci self.run_and_compare(func, 9487db96d56Sopenharmony_ci [(0, 'call'), 9497db96d56Sopenharmony_ci (1, 'line'), 9507db96d56Sopenharmony_ci (2, 'line'), 9517db96d56Sopenharmony_ci (3, 'line'), 9527db96d56Sopenharmony_ci (4, 'line'), 9537db96d56Sopenharmony_ci (5, 'line'), 9547db96d56Sopenharmony_ci (6, 'line'), 9557db96d56Sopenharmony_ci (3, 'line'), 9567db96d56Sopenharmony_ci (3, 'return')]) 9577db96d56Sopenharmony_ci 9587db96d56Sopenharmony_ci def test_break_to_break(self): 9597db96d56Sopenharmony_ci 9607db96d56Sopenharmony_ci def func(): 9617db96d56Sopenharmony_ci TRUE = 1 9627db96d56Sopenharmony_ci while TRUE: 9637db96d56Sopenharmony_ci while TRUE: 9647db96d56Sopenharmony_ci break 9657db96d56Sopenharmony_ci break 9667db96d56Sopenharmony_ci 9677db96d56Sopenharmony_ci self.run_and_compare(func, 9687db96d56Sopenharmony_ci [(0, 'call'), 9697db96d56Sopenharmony_ci (1, 'line'), 9707db96d56Sopenharmony_ci (2, 'line'), 9717db96d56Sopenharmony_ci (3, 'line'), 9727db96d56Sopenharmony_ci (4, 'line'), 9737db96d56Sopenharmony_ci (5, 'line'), 9747db96d56Sopenharmony_ci (5, 'return')]) 9757db96d56Sopenharmony_ci 9767db96d56Sopenharmony_ci def test_nested_ifs(self): 9777db96d56Sopenharmony_ci 9787db96d56Sopenharmony_ci def func(): 9797db96d56Sopenharmony_ci a = b = 1 9807db96d56Sopenharmony_ci if a == 1: 9817db96d56Sopenharmony_ci if b == 1: 9827db96d56Sopenharmony_ci x = 4 9837db96d56Sopenharmony_ci else: 9847db96d56Sopenharmony_ci y = 6 9857db96d56Sopenharmony_ci else: 9867db96d56Sopenharmony_ci z = 8 9877db96d56Sopenharmony_ci 9887db96d56Sopenharmony_ci self.run_and_compare(func, 9897db96d56Sopenharmony_ci [(0, 'call'), 9907db96d56Sopenharmony_ci (1, 'line'), 9917db96d56Sopenharmony_ci (2, 'line'), 9927db96d56Sopenharmony_ci (3, 'line'), 9937db96d56Sopenharmony_ci (4, 'line'), 9947db96d56Sopenharmony_ci (4, 'return')]) 9957db96d56Sopenharmony_ci 9967db96d56Sopenharmony_ci def test_nested_ifs_with_and(self): 9977db96d56Sopenharmony_ci 9987db96d56Sopenharmony_ci def func(): 9997db96d56Sopenharmony_ci if A: 10007db96d56Sopenharmony_ci if B: 10017db96d56Sopenharmony_ci if C: 10027db96d56Sopenharmony_ci if D: 10037db96d56Sopenharmony_ci return False 10047db96d56Sopenharmony_ci else: 10057db96d56Sopenharmony_ci return False 10067db96d56Sopenharmony_ci elif E and F: 10077db96d56Sopenharmony_ci return True 10087db96d56Sopenharmony_ci 10097db96d56Sopenharmony_ci A = B = True 10107db96d56Sopenharmony_ci C = False 10117db96d56Sopenharmony_ci 10127db96d56Sopenharmony_ci self.run_and_compare(func, 10137db96d56Sopenharmony_ci [(0, 'call'), 10147db96d56Sopenharmony_ci (1, 'line'), 10157db96d56Sopenharmony_ci (2, 'line'), 10167db96d56Sopenharmony_ci (3, 'line'), 10177db96d56Sopenharmony_ci (3, 'return')]) 10187db96d56Sopenharmony_ci 10197db96d56Sopenharmony_ci def test_nested_try_if(self): 10207db96d56Sopenharmony_ci 10217db96d56Sopenharmony_ci def func(): 10227db96d56Sopenharmony_ci x = "hello" 10237db96d56Sopenharmony_ci try: 10247db96d56Sopenharmony_ci 3/0 10257db96d56Sopenharmony_ci except ZeroDivisionError: 10267db96d56Sopenharmony_ci if x == 'raise': 10277db96d56Sopenharmony_ci raise ValueError() # line 6 10287db96d56Sopenharmony_ci f = 7 10297db96d56Sopenharmony_ci 10307db96d56Sopenharmony_ci self.run_and_compare(func, 10317db96d56Sopenharmony_ci [(0, 'call'), 10327db96d56Sopenharmony_ci (1, 'line'), 10337db96d56Sopenharmony_ci (2, 'line'), 10347db96d56Sopenharmony_ci (3, 'line'), 10357db96d56Sopenharmony_ci (3, 'exception'), 10367db96d56Sopenharmony_ci (4, 'line'), 10377db96d56Sopenharmony_ci (5, 'line'), 10387db96d56Sopenharmony_ci (7, 'line'), 10397db96d56Sopenharmony_ci (7, 'return')]) 10407db96d56Sopenharmony_ci 10417db96d56Sopenharmony_ci def test_if_false_in_with(self): 10427db96d56Sopenharmony_ci 10437db96d56Sopenharmony_ci class C: 10447db96d56Sopenharmony_ci def __enter__(self): 10457db96d56Sopenharmony_ci return self 10467db96d56Sopenharmony_ci def __exit__(*args): 10477db96d56Sopenharmony_ci pass 10487db96d56Sopenharmony_ci 10497db96d56Sopenharmony_ci def func(): 10507db96d56Sopenharmony_ci with C(): 10517db96d56Sopenharmony_ci if False: 10527db96d56Sopenharmony_ci pass 10537db96d56Sopenharmony_ci 10547db96d56Sopenharmony_ci self.run_and_compare(func, 10557db96d56Sopenharmony_ci [(0, 'call'), 10567db96d56Sopenharmony_ci (1, 'line'), 10577db96d56Sopenharmony_ci (-5, 'call'), 10587db96d56Sopenharmony_ci (-4, 'line'), 10597db96d56Sopenharmony_ci (-4, 'return'), 10607db96d56Sopenharmony_ci (2, 'line'), 10617db96d56Sopenharmony_ci (1, 'line'), 10627db96d56Sopenharmony_ci (-3, 'call'), 10637db96d56Sopenharmony_ci (-2, 'line'), 10647db96d56Sopenharmony_ci (-2, 'return'), 10657db96d56Sopenharmony_ci (1, 'return')]) 10667db96d56Sopenharmony_ci 10677db96d56Sopenharmony_ci def test_if_false_in_try_except(self): 10687db96d56Sopenharmony_ci 10697db96d56Sopenharmony_ci def func(): 10707db96d56Sopenharmony_ci try: 10717db96d56Sopenharmony_ci if False: 10727db96d56Sopenharmony_ci pass 10737db96d56Sopenharmony_ci except Exception: 10747db96d56Sopenharmony_ci X 10757db96d56Sopenharmony_ci 10767db96d56Sopenharmony_ci self.run_and_compare(func, 10777db96d56Sopenharmony_ci [(0, 'call'), 10787db96d56Sopenharmony_ci (1, 'line'), 10797db96d56Sopenharmony_ci (2, 'line'), 10807db96d56Sopenharmony_ci (2, 'return')]) 10817db96d56Sopenharmony_ci 10827db96d56Sopenharmony_ci def test_implicit_return_in_class(self): 10837db96d56Sopenharmony_ci 10847db96d56Sopenharmony_ci def func(): 10857db96d56Sopenharmony_ci class A: 10867db96d56Sopenharmony_ci if 3 < 9: 10877db96d56Sopenharmony_ci a = 1 10887db96d56Sopenharmony_ci else: 10897db96d56Sopenharmony_ci a = 2 10907db96d56Sopenharmony_ci 10917db96d56Sopenharmony_ci self.run_and_compare(func, 10927db96d56Sopenharmony_ci [(0, 'call'), 10937db96d56Sopenharmony_ci (1, 'line'), 10947db96d56Sopenharmony_ci (1, 'call'), 10957db96d56Sopenharmony_ci (1, 'line'), 10967db96d56Sopenharmony_ci (2, 'line'), 10977db96d56Sopenharmony_ci (3, 'line'), 10987db96d56Sopenharmony_ci (3, 'return'), 10997db96d56Sopenharmony_ci (1, 'return')]) 11007db96d56Sopenharmony_ci 11017db96d56Sopenharmony_ci def test_try_in_try(self): 11027db96d56Sopenharmony_ci def func(): 11037db96d56Sopenharmony_ci try: 11047db96d56Sopenharmony_ci try: 11057db96d56Sopenharmony_ci pass 11067db96d56Sopenharmony_ci except Exception as ex: 11077db96d56Sopenharmony_ci pass 11087db96d56Sopenharmony_ci except Exception: 11097db96d56Sopenharmony_ci pass 11107db96d56Sopenharmony_ci 11117db96d56Sopenharmony_ci self.run_and_compare(func, 11127db96d56Sopenharmony_ci [(0, 'call'), 11137db96d56Sopenharmony_ci (1, 'line'), 11147db96d56Sopenharmony_ci (2, 'line'), 11157db96d56Sopenharmony_ci (3, 'line'), 11167db96d56Sopenharmony_ci (3, 'return')]) 11177db96d56Sopenharmony_ci 11187db96d56Sopenharmony_ci def test_try_in_try_with_exception(self): 11197db96d56Sopenharmony_ci 11207db96d56Sopenharmony_ci def func(): 11217db96d56Sopenharmony_ci try: 11227db96d56Sopenharmony_ci try: 11237db96d56Sopenharmony_ci raise TypeError 11247db96d56Sopenharmony_ci except ValueError as ex: 11257db96d56Sopenharmony_ci 5 11267db96d56Sopenharmony_ci except TypeError: 11277db96d56Sopenharmony_ci 7 11287db96d56Sopenharmony_ci 11297db96d56Sopenharmony_ci self.run_and_compare(func, 11307db96d56Sopenharmony_ci [(0, 'call'), 11317db96d56Sopenharmony_ci (1, 'line'), 11327db96d56Sopenharmony_ci (2, 'line'), 11337db96d56Sopenharmony_ci (3, 'line'), 11347db96d56Sopenharmony_ci (3, 'exception'), 11357db96d56Sopenharmony_ci (4, 'line'), 11367db96d56Sopenharmony_ci (6, 'line'), 11377db96d56Sopenharmony_ci (7, 'line'), 11387db96d56Sopenharmony_ci (7, 'return')]) 11397db96d56Sopenharmony_ci 11407db96d56Sopenharmony_ci def func(): 11417db96d56Sopenharmony_ci try: 11427db96d56Sopenharmony_ci try: 11437db96d56Sopenharmony_ci raise ValueError 11447db96d56Sopenharmony_ci except ValueError as ex: 11457db96d56Sopenharmony_ci 5 11467db96d56Sopenharmony_ci except TypeError: 11477db96d56Sopenharmony_ci 7 11487db96d56Sopenharmony_ci 11497db96d56Sopenharmony_ci self.run_and_compare(func, 11507db96d56Sopenharmony_ci [(0, 'call'), 11517db96d56Sopenharmony_ci (1, 'line'), 11527db96d56Sopenharmony_ci (2, 'line'), 11537db96d56Sopenharmony_ci (3, 'line'), 11547db96d56Sopenharmony_ci (3, 'exception'), 11557db96d56Sopenharmony_ci (4, 'line'), 11567db96d56Sopenharmony_ci (5, 'line'), 11577db96d56Sopenharmony_ci (5, 'return')]) 11587db96d56Sopenharmony_ci 11597db96d56Sopenharmony_ci def test_if_in_if_in_if(self): 11607db96d56Sopenharmony_ci def func(a=0, p=1, z=1): 11617db96d56Sopenharmony_ci if p: 11627db96d56Sopenharmony_ci if a: 11637db96d56Sopenharmony_ci if z: 11647db96d56Sopenharmony_ci pass 11657db96d56Sopenharmony_ci else: 11667db96d56Sopenharmony_ci pass 11677db96d56Sopenharmony_ci else: 11687db96d56Sopenharmony_ci pass 11697db96d56Sopenharmony_ci 11707db96d56Sopenharmony_ci self.run_and_compare(func, 11717db96d56Sopenharmony_ci [(0, 'call'), 11727db96d56Sopenharmony_ci (1, 'line'), 11737db96d56Sopenharmony_ci (2, 'line'), 11747db96d56Sopenharmony_ci (2, 'return')]) 11757db96d56Sopenharmony_ci 11767db96d56Sopenharmony_ci def test_early_exit_with(self): 11777db96d56Sopenharmony_ci 11787db96d56Sopenharmony_ci class C: 11797db96d56Sopenharmony_ci def __enter__(self): 11807db96d56Sopenharmony_ci return self 11817db96d56Sopenharmony_ci def __exit__(*args): 11827db96d56Sopenharmony_ci pass 11837db96d56Sopenharmony_ci 11847db96d56Sopenharmony_ci def func_break(): 11857db96d56Sopenharmony_ci for i in (1,2): 11867db96d56Sopenharmony_ci with C(): 11877db96d56Sopenharmony_ci break 11887db96d56Sopenharmony_ci pass 11897db96d56Sopenharmony_ci 11907db96d56Sopenharmony_ci def func_return(): 11917db96d56Sopenharmony_ci with C(): 11927db96d56Sopenharmony_ci return 11937db96d56Sopenharmony_ci 11947db96d56Sopenharmony_ci self.run_and_compare(func_break, 11957db96d56Sopenharmony_ci [(0, 'call'), 11967db96d56Sopenharmony_ci (1, 'line'), 11977db96d56Sopenharmony_ci (2, 'line'), 11987db96d56Sopenharmony_ci (-5, 'call'), 11997db96d56Sopenharmony_ci (-4, 'line'), 12007db96d56Sopenharmony_ci (-4, 'return'), 12017db96d56Sopenharmony_ci (3, 'line'), 12027db96d56Sopenharmony_ci (2, 'line'), 12037db96d56Sopenharmony_ci (-3, 'call'), 12047db96d56Sopenharmony_ci (-2, 'line'), 12057db96d56Sopenharmony_ci (-2, 'return'), 12067db96d56Sopenharmony_ci (4, 'line'), 12077db96d56Sopenharmony_ci (4, 'return')]) 12087db96d56Sopenharmony_ci 12097db96d56Sopenharmony_ci self.run_and_compare(func_return, 12107db96d56Sopenharmony_ci [(0, 'call'), 12117db96d56Sopenharmony_ci (1, 'line'), 12127db96d56Sopenharmony_ci (-11, 'call'), 12137db96d56Sopenharmony_ci (-10, 'line'), 12147db96d56Sopenharmony_ci (-10, 'return'), 12157db96d56Sopenharmony_ci (2, 'line'), 12167db96d56Sopenharmony_ci (1, 'line'), 12177db96d56Sopenharmony_ci (-9, 'call'), 12187db96d56Sopenharmony_ci (-8, 'line'), 12197db96d56Sopenharmony_ci (-8, 'return'), 12207db96d56Sopenharmony_ci (1, 'return')]) 12217db96d56Sopenharmony_ci 12227db96d56Sopenharmony_ci def test_flow_converges_on_same_line(self): 12237db96d56Sopenharmony_ci 12247db96d56Sopenharmony_ci def foo(x): 12257db96d56Sopenharmony_ci if x: 12267db96d56Sopenharmony_ci try: 12277db96d56Sopenharmony_ci 1/(x - 1) 12287db96d56Sopenharmony_ci except ZeroDivisionError: 12297db96d56Sopenharmony_ci pass 12307db96d56Sopenharmony_ci return x 12317db96d56Sopenharmony_ci 12327db96d56Sopenharmony_ci def func(): 12337db96d56Sopenharmony_ci for i in range(2): 12347db96d56Sopenharmony_ci foo(i) 12357db96d56Sopenharmony_ci 12367db96d56Sopenharmony_ci self.run_and_compare(func, 12377db96d56Sopenharmony_ci [(0, 'call'), 12387db96d56Sopenharmony_ci (1, 'line'), 12397db96d56Sopenharmony_ci (2, 'line'), 12407db96d56Sopenharmony_ci (-8, 'call'), 12417db96d56Sopenharmony_ci (-7, 'line'), 12427db96d56Sopenharmony_ci (-2, 'line'), 12437db96d56Sopenharmony_ci (-2, 'return'), 12447db96d56Sopenharmony_ci (1, 'line'), 12457db96d56Sopenharmony_ci (2, 'line'), 12467db96d56Sopenharmony_ci (-8, 'call'), 12477db96d56Sopenharmony_ci (-7, 'line'), 12487db96d56Sopenharmony_ci (-6, 'line'), 12497db96d56Sopenharmony_ci (-5, 'line'), 12507db96d56Sopenharmony_ci (-5, 'exception'), 12517db96d56Sopenharmony_ci (-4, 'line'), 12527db96d56Sopenharmony_ci (-3, 'line'), 12537db96d56Sopenharmony_ci (-2, 'line'), 12547db96d56Sopenharmony_ci (-2, 'return'), 12557db96d56Sopenharmony_ci (1, 'line'), 12567db96d56Sopenharmony_ci (1, 'return')]) 12577db96d56Sopenharmony_ci 12587db96d56Sopenharmony_ci def test_no_tracing_of_named_except_cleanup(self): 12597db96d56Sopenharmony_ci 12607db96d56Sopenharmony_ci def func(): 12617db96d56Sopenharmony_ci x = 0 12627db96d56Sopenharmony_ci try: 12637db96d56Sopenharmony_ci 1/x 12647db96d56Sopenharmony_ci except ZeroDivisionError as error: 12657db96d56Sopenharmony_ci if x: 12667db96d56Sopenharmony_ci raise 12677db96d56Sopenharmony_ci return "done" 12687db96d56Sopenharmony_ci 12697db96d56Sopenharmony_ci self.run_and_compare(func, 12707db96d56Sopenharmony_ci [(0, 'call'), 12717db96d56Sopenharmony_ci (1, 'line'), 12727db96d56Sopenharmony_ci (2, 'line'), 12737db96d56Sopenharmony_ci (3, 'line'), 12747db96d56Sopenharmony_ci (3, 'exception'), 12757db96d56Sopenharmony_ci (4, 'line'), 12767db96d56Sopenharmony_ci (5, 'line'), 12777db96d56Sopenharmony_ci (7, 'line'), 12787db96d56Sopenharmony_ci (7, 'return')]) 12797db96d56Sopenharmony_ci 12807db96d56Sopenharmony_ci def test_tracing_exception_raised_in_with(self): 12817db96d56Sopenharmony_ci 12827db96d56Sopenharmony_ci class NullCtx: 12837db96d56Sopenharmony_ci def __enter__(self): 12847db96d56Sopenharmony_ci return self 12857db96d56Sopenharmony_ci def __exit__(self, *excinfo): 12867db96d56Sopenharmony_ci pass 12877db96d56Sopenharmony_ci 12887db96d56Sopenharmony_ci def func(): 12897db96d56Sopenharmony_ci try: 12907db96d56Sopenharmony_ci with NullCtx(): 12917db96d56Sopenharmony_ci 1/0 12927db96d56Sopenharmony_ci except ZeroDivisionError: 12937db96d56Sopenharmony_ci pass 12947db96d56Sopenharmony_ci 12957db96d56Sopenharmony_ci self.run_and_compare(func, 12967db96d56Sopenharmony_ci [(0, 'call'), 12977db96d56Sopenharmony_ci (1, 'line'), 12987db96d56Sopenharmony_ci (2, 'line'), 12997db96d56Sopenharmony_ci (-5, 'call'), 13007db96d56Sopenharmony_ci (-4, 'line'), 13017db96d56Sopenharmony_ci (-4, 'return'), 13027db96d56Sopenharmony_ci (3, 'line'), 13037db96d56Sopenharmony_ci (3, 'exception'), 13047db96d56Sopenharmony_ci (2, 'line'), 13057db96d56Sopenharmony_ci (-3, 'call'), 13067db96d56Sopenharmony_ci (-2, 'line'), 13077db96d56Sopenharmony_ci (-2, 'return'), 13087db96d56Sopenharmony_ci (4, 'line'), 13097db96d56Sopenharmony_ci (5, 'line'), 13107db96d56Sopenharmony_ci (5, 'return')]) 13117db96d56Sopenharmony_ci 13127db96d56Sopenharmony_ci def test_try_except_star_no_exception(self): 13137db96d56Sopenharmony_ci 13147db96d56Sopenharmony_ci def func(): 13157db96d56Sopenharmony_ci try: 13167db96d56Sopenharmony_ci 2 13177db96d56Sopenharmony_ci except* Exception: 13187db96d56Sopenharmony_ci 4 13197db96d56Sopenharmony_ci else: 13207db96d56Sopenharmony_ci 6 13217db96d56Sopenharmony_ci if False: 13227db96d56Sopenharmony_ci 8 13237db96d56Sopenharmony_ci else: 13247db96d56Sopenharmony_ci 10 13257db96d56Sopenharmony_ci if func.__name__ == 'Fred': 13267db96d56Sopenharmony_ci 12 13277db96d56Sopenharmony_ci finally: 13287db96d56Sopenharmony_ci 14 13297db96d56Sopenharmony_ci 13307db96d56Sopenharmony_ci self.run_and_compare(func, 13317db96d56Sopenharmony_ci [(0, 'call'), 13327db96d56Sopenharmony_ci (1, 'line'), 13337db96d56Sopenharmony_ci (2, 'line'), 13347db96d56Sopenharmony_ci (6, 'line'), 13357db96d56Sopenharmony_ci (7, 'line'), 13367db96d56Sopenharmony_ci (10, 'line'), 13377db96d56Sopenharmony_ci (11, 'line'), 13387db96d56Sopenharmony_ci (14, 'line'), 13397db96d56Sopenharmony_ci (14, 'return')]) 13407db96d56Sopenharmony_ci 13417db96d56Sopenharmony_ci def test_try_except_star_named_no_exception(self): 13427db96d56Sopenharmony_ci 13437db96d56Sopenharmony_ci def func(): 13447db96d56Sopenharmony_ci try: 13457db96d56Sopenharmony_ci 2 13467db96d56Sopenharmony_ci except* Exception as e: 13477db96d56Sopenharmony_ci 4 13487db96d56Sopenharmony_ci else: 13497db96d56Sopenharmony_ci 6 13507db96d56Sopenharmony_ci finally: 13517db96d56Sopenharmony_ci 8 13527db96d56Sopenharmony_ci 13537db96d56Sopenharmony_ci self.run_and_compare(func, 13547db96d56Sopenharmony_ci [(0, 'call'), 13557db96d56Sopenharmony_ci (1, 'line'), 13567db96d56Sopenharmony_ci (2, 'line'), 13577db96d56Sopenharmony_ci (6, 'line'), 13587db96d56Sopenharmony_ci (8, 'line'), 13597db96d56Sopenharmony_ci (8, 'return')]) 13607db96d56Sopenharmony_ci 13617db96d56Sopenharmony_ci def test_try_except_star_exception_caught(self): 13627db96d56Sopenharmony_ci 13637db96d56Sopenharmony_ci def func(): 13647db96d56Sopenharmony_ci try: 13657db96d56Sopenharmony_ci raise ValueError(2) 13667db96d56Sopenharmony_ci except* ValueError: 13677db96d56Sopenharmony_ci 4 13687db96d56Sopenharmony_ci else: 13697db96d56Sopenharmony_ci 6 13707db96d56Sopenharmony_ci finally: 13717db96d56Sopenharmony_ci 8 13727db96d56Sopenharmony_ci 13737db96d56Sopenharmony_ci self.run_and_compare(func, 13747db96d56Sopenharmony_ci [(0, 'call'), 13757db96d56Sopenharmony_ci (1, 'line'), 13767db96d56Sopenharmony_ci (2, 'line'), 13777db96d56Sopenharmony_ci (2, 'exception'), 13787db96d56Sopenharmony_ci (3, 'line'), 13797db96d56Sopenharmony_ci (4, 'line'), 13807db96d56Sopenharmony_ci (8, 'line'), 13817db96d56Sopenharmony_ci (8, 'return')]) 13827db96d56Sopenharmony_ci 13837db96d56Sopenharmony_ci def test_try_except_star_named_exception_caught(self): 13847db96d56Sopenharmony_ci 13857db96d56Sopenharmony_ci def func(): 13867db96d56Sopenharmony_ci try: 13877db96d56Sopenharmony_ci raise ValueError(2) 13887db96d56Sopenharmony_ci except* ValueError as e: 13897db96d56Sopenharmony_ci 4 13907db96d56Sopenharmony_ci else: 13917db96d56Sopenharmony_ci 6 13927db96d56Sopenharmony_ci finally: 13937db96d56Sopenharmony_ci 8 13947db96d56Sopenharmony_ci 13957db96d56Sopenharmony_ci self.run_and_compare(func, 13967db96d56Sopenharmony_ci [(0, 'call'), 13977db96d56Sopenharmony_ci (1, 'line'), 13987db96d56Sopenharmony_ci (2, 'line'), 13997db96d56Sopenharmony_ci (2, 'exception'), 14007db96d56Sopenharmony_ci (3, 'line'), 14017db96d56Sopenharmony_ci (4, 'line'), 14027db96d56Sopenharmony_ci (8, 'line'), 14037db96d56Sopenharmony_ci (8, 'return')]) 14047db96d56Sopenharmony_ci 14057db96d56Sopenharmony_ci def test_try_except_star_exception_not_caught(self): 14067db96d56Sopenharmony_ci 14077db96d56Sopenharmony_ci def func(): 14087db96d56Sopenharmony_ci try: 14097db96d56Sopenharmony_ci try: 14107db96d56Sopenharmony_ci raise ValueError(3) 14117db96d56Sopenharmony_ci except* TypeError: 14127db96d56Sopenharmony_ci 5 14137db96d56Sopenharmony_ci except ValueError: 14147db96d56Sopenharmony_ci 7 14157db96d56Sopenharmony_ci 14167db96d56Sopenharmony_ci self.run_and_compare(func, 14177db96d56Sopenharmony_ci [(0, 'call'), 14187db96d56Sopenharmony_ci (1, 'line'), 14197db96d56Sopenharmony_ci (2, 'line'), 14207db96d56Sopenharmony_ci (3, 'line'), 14217db96d56Sopenharmony_ci (3, 'exception'), 14227db96d56Sopenharmony_ci (4, 'line'), 14237db96d56Sopenharmony_ci (6, 'line'), 14247db96d56Sopenharmony_ci (7, 'line'), 14257db96d56Sopenharmony_ci (7, 'return')]) 14267db96d56Sopenharmony_ci 14277db96d56Sopenharmony_ci def test_try_except_star_named_exception_not_caught(self): 14287db96d56Sopenharmony_ci 14297db96d56Sopenharmony_ci def func(): 14307db96d56Sopenharmony_ci try: 14317db96d56Sopenharmony_ci try: 14327db96d56Sopenharmony_ci raise ValueError(3) 14337db96d56Sopenharmony_ci except* TypeError as e: 14347db96d56Sopenharmony_ci 5 14357db96d56Sopenharmony_ci except ValueError: 14367db96d56Sopenharmony_ci 7 14377db96d56Sopenharmony_ci 14387db96d56Sopenharmony_ci self.run_and_compare(func, 14397db96d56Sopenharmony_ci [(0, 'call'), 14407db96d56Sopenharmony_ci (1, 'line'), 14417db96d56Sopenharmony_ci (2, 'line'), 14427db96d56Sopenharmony_ci (3, 'line'), 14437db96d56Sopenharmony_ci (3, 'exception'), 14447db96d56Sopenharmony_ci (4, 'line'), 14457db96d56Sopenharmony_ci (6, 'line'), 14467db96d56Sopenharmony_ci (7, 'line'), 14477db96d56Sopenharmony_ci (7, 'return')]) 14487db96d56Sopenharmony_ci 14497db96d56Sopenharmony_ci def test_try_except_star_nested(self): 14507db96d56Sopenharmony_ci 14517db96d56Sopenharmony_ci def func(): 14527db96d56Sopenharmony_ci try: 14537db96d56Sopenharmony_ci try: 14547db96d56Sopenharmony_ci raise ExceptionGroup( 14557db96d56Sopenharmony_ci 'eg', 14567db96d56Sopenharmony_ci [ValueError(5), TypeError('bad type')]) 14577db96d56Sopenharmony_ci except* TypeError as e: 14587db96d56Sopenharmony_ci 7 14597db96d56Sopenharmony_ci except* OSError: 14607db96d56Sopenharmony_ci 9 14617db96d56Sopenharmony_ci except* ValueError: 14627db96d56Sopenharmony_ci raise 14637db96d56Sopenharmony_ci except* ValueError: 14647db96d56Sopenharmony_ci try: 14657db96d56Sopenharmony_ci raise TypeError(14) 14667db96d56Sopenharmony_ci except* OSError: 14677db96d56Sopenharmony_ci 16 14687db96d56Sopenharmony_ci except* TypeError as e: 14697db96d56Sopenharmony_ci 18 14707db96d56Sopenharmony_ci return 0 14717db96d56Sopenharmony_ci 14727db96d56Sopenharmony_ci self.run_and_compare(func, 14737db96d56Sopenharmony_ci [(0, 'call'), 14747db96d56Sopenharmony_ci (1, 'line'), 14757db96d56Sopenharmony_ci (2, 'line'), 14767db96d56Sopenharmony_ci (3, 'line'), 14777db96d56Sopenharmony_ci (4, 'line'), 14787db96d56Sopenharmony_ci (5, 'line'), 14797db96d56Sopenharmony_ci (3, 'line'), 14807db96d56Sopenharmony_ci (3, 'exception'), 14817db96d56Sopenharmony_ci (6, 'line'), 14827db96d56Sopenharmony_ci (7, 'line'), 14837db96d56Sopenharmony_ci (8, 'line'), 14847db96d56Sopenharmony_ci (10, 'line'), 14857db96d56Sopenharmony_ci (11, 'line'), 14867db96d56Sopenharmony_ci (12, 'line'), 14877db96d56Sopenharmony_ci (13, 'line'), 14887db96d56Sopenharmony_ci (14, 'line'), 14897db96d56Sopenharmony_ci (14, 'exception'), 14907db96d56Sopenharmony_ci (15, 'line'), 14917db96d56Sopenharmony_ci (17, 'line'), 14927db96d56Sopenharmony_ci (18, 'line'), 14937db96d56Sopenharmony_ci (19, 'line'), 14947db96d56Sopenharmony_ci (19, 'return')]) 14957db96d56Sopenharmony_ci 14967db96d56Sopenharmony_ci def test_notrace_lambda(self): 14977db96d56Sopenharmony_ci #Regression test for issue 46314 14987db96d56Sopenharmony_ci 14997db96d56Sopenharmony_ci def func(): 15007db96d56Sopenharmony_ci 1 15017db96d56Sopenharmony_ci lambda x: 2 15027db96d56Sopenharmony_ci 3 15037db96d56Sopenharmony_ci 15047db96d56Sopenharmony_ci self.run_and_compare(func, 15057db96d56Sopenharmony_ci [(0, 'call'), 15067db96d56Sopenharmony_ci (1, 'line'), 15077db96d56Sopenharmony_ci (2, 'line'), 15087db96d56Sopenharmony_ci (3, 'line'), 15097db96d56Sopenharmony_ci (3, 'return')]) 15107db96d56Sopenharmony_ci 15117db96d56Sopenharmony_ci def test_class_creation_with_docstrings(self): 15127db96d56Sopenharmony_ci 15137db96d56Sopenharmony_ci def func(): 15147db96d56Sopenharmony_ci class Class_1: 15157db96d56Sopenharmony_ci ''' the docstring. 2''' 15167db96d56Sopenharmony_ci def __init__(self): 15177db96d56Sopenharmony_ci ''' Another docstring. 4''' 15187db96d56Sopenharmony_ci self.a = 5 15197db96d56Sopenharmony_ci 15207db96d56Sopenharmony_ci self.run_and_compare(func, 15217db96d56Sopenharmony_ci [(0, 'call'), 15227db96d56Sopenharmony_ci (1, 'line'), 15237db96d56Sopenharmony_ci (1, 'call'), 15247db96d56Sopenharmony_ci (1, 'line'), 15257db96d56Sopenharmony_ci (2, 'line'), 15267db96d56Sopenharmony_ci (3, 'line'), 15277db96d56Sopenharmony_ci (3, 'return'), 15287db96d56Sopenharmony_ci (1, 'return')]) 15297db96d56Sopenharmony_ci 15307db96d56Sopenharmony_ci @support.cpython_only 15317db96d56Sopenharmony_ci def test_no_line_event_after_creating_generator(self): 15327db96d56Sopenharmony_ci # Spurious line events before call events only show up with C tracer 15337db96d56Sopenharmony_ci 15347db96d56Sopenharmony_ci # Skip this test if the _testcapi module isn't available. 15357db96d56Sopenharmony_ci _testcapi = import_helper.import_module('_testcapi') 15367db96d56Sopenharmony_ci 15377db96d56Sopenharmony_ci def gen(): 15387db96d56Sopenharmony_ci yield 1 15397db96d56Sopenharmony_ci 15407db96d56Sopenharmony_ci def func(): 15417db96d56Sopenharmony_ci for _ in ( 15427db96d56Sopenharmony_ci gen() 15437db96d56Sopenharmony_ci ): 15447db96d56Sopenharmony_ci pass 15457db96d56Sopenharmony_ci 15467db96d56Sopenharmony_ci EXPECTED_EVENTS = [ 15477db96d56Sopenharmony_ci (0, 'call'), 15487db96d56Sopenharmony_ci (2, 'line'), 15497db96d56Sopenharmony_ci (1, 'line'), 15507db96d56Sopenharmony_ci (-3, 'call'), 15517db96d56Sopenharmony_ci (-2, 'line'), 15527db96d56Sopenharmony_ci (-2, 'return'), 15537db96d56Sopenharmony_ci (4, 'line'), 15547db96d56Sopenharmony_ci (1, 'line'), 15557db96d56Sopenharmony_ci (-2, 'call'), 15567db96d56Sopenharmony_ci (-2, 'return'), 15577db96d56Sopenharmony_ci (1, 'return'), 15587db96d56Sopenharmony_ci ] 15597db96d56Sopenharmony_ci 15607db96d56Sopenharmony_ci # C level events should be the same as expected and the same as Python level. 15617db96d56Sopenharmony_ci 15627db96d56Sopenharmony_ci events = [] 15637db96d56Sopenharmony_ci # Turning on and off tracing must be on same line to avoid unwanted LINE events. 15647db96d56Sopenharmony_ci _testcapi.settrace_to_record(events); func(); sys.settrace(None) 15657db96d56Sopenharmony_ci start_line = func.__code__.co_firstlineno 15667db96d56Sopenharmony_ci events = [ 15677db96d56Sopenharmony_ci (line-start_line, EVENT_NAMES[what]) 15687db96d56Sopenharmony_ci for (what, line, arg) in events 15697db96d56Sopenharmony_ci ] 15707db96d56Sopenharmony_ci self.assertEqual(events, EXPECTED_EVENTS) 15717db96d56Sopenharmony_ci 15727db96d56Sopenharmony_ci self.run_and_compare(func, EXPECTED_EVENTS) 15737db96d56Sopenharmony_ci 15747db96d56Sopenharmony_ci def test_settrace_error(self): 15757db96d56Sopenharmony_ci 15767db96d56Sopenharmony_ci raised = False 15777db96d56Sopenharmony_ci def error_once(frame, event, arg): 15787db96d56Sopenharmony_ci nonlocal raised 15797db96d56Sopenharmony_ci if not raised: 15807db96d56Sopenharmony_ci raised = True 15817db96d56Sopenharmony_ci raise Exception 15827db96d56Sopenharmony_ci return error 15837db96d56Sopenharmony_ci 15847db96d56Sopenharmony_ci try: 15857db96d56Sopenharmony_ci sys._getframe().f_trace = error_once 15867db96d56Sopenharmony_ci sys.settrace(error_once) 15877db96d56Sopenharmony_ci len([]) 15887db96d56Sopenharmony_ci except Exception as ex: 15897db96d56Sopenharmony_ci count = 0 15907db96d56Sopenharmony_ci tb = ex.__traceback__ 15917db96d56Sopenharmony_ci print(tb) 15927db96d56Sopenharmony_ci while tb: 15937db96d56Sopenharmony_ci if tb.tb_frame.f_code.co_name == "test_settrace_error": 15947db96d56Sopenharmony_ci count += 1 15957db96d56Sopenharmony_ci tb = tb.tb_next 15967db96d56Sopenharmony_ci if count == 0: 15977db96d56Sopenharmony_ci self.fail("Traceback is missing frame") 15987db96d56Sopenharmony_ci elif count > 1: 15997db96d56Sopenharmony_ci self.fail("Traceback has frame more than once") 16007db96d56Sopenharmony_ci else: 16017db96d56Sopenharmony_ci self.fail("No exception raised") 16027db96d56Sopenharmony_ci finally: 16037db96d56Sopenharmony_ci sys.settrace(None) 16047db96d56Sopenharmony_ci 16057db96d56Sopenharmony_ci @support.cpython_only 16067db96d56Sopenharmony_ci def test_testcapi_settrace_error(self): 16077db96d56Sopenharmony_ci 16087db96d56Sopenharmony_ci # Skip this test if the _testcapi module isn't available. 16097db96d56Sopenharmony_ci _testcapi = import_helper.import_module('_testcapi') 16107db96d56Sopenharmony_ci 16117db96d56Sopenharmony_ci try: 16127db96d56Sopenharmony_ci _testcapi.settrace_to_error([]) 16137db96d56Sopenharmony_ci len([]) 16147db96d56Sopenharmony_ci except Exception as ex: 16157db96d56Sopenharmony_ci count = 0 16167db96d56Sopenharmony_ci tb = ex.__traceback__ 16177db96d56Sopenharmony_ci while tb: 16187db96d56Sopenharmony_ci if tb.tb_frame.f_code.co_name == "test_testcapi_settrace_error": 16197db96d56Sopenharmony_ci count += 1 16207db96d56Sopenharmony_ci tb = tb.tb_next 16217db96d56Sopenharmony_ci if count == 0: 16227db96d56Sopenharmony_ci self.fail("Traceback is missing frame") 16237db96d56Sopenharmony_ci elif count > 1: 16247db96d56Sopenharmony_ci self.fail("Traceback has frame more than once") 16257db96d56Sopenharmony_ci else: 16267db96d56Sopenharmony_ci self.fail("No exception raised") 16277db96d56Sopenharmony_ci finally: 16287db96d56Sopenharmony_ci sys.settrace(None) 16297db96d56Sopenharmony_ci 16307db96d56Sopenharmony_ci def test_very_large_function(self): 16317db96d56Sopenharmony_ci # There is a separate code path when the number of lines > (1 << 15). 16327db96d56Sopenharmony_ci d = {} 16337db96d56Sopenharmony_ci exec("""def f(): # line 0 16347db96d56Sopenharmony_ci x = 0 # line 1 16357db96d56Sopenharmony_ci y = 1 # line 2 16367db96d56Sopenharmony_ci %s # lines 3 through (1 << 16) 16377db96d56Sopenharmony_ci x += 1 # 16387db96d56Sopenharmony_ci return""" % ('\n' * (1 << 16),), d) 16397db96d56Sopenharmony_ci f = d['f'] 16407db96d56Sopenharmony_ci 16417db96d56Sopenharmony_ci EXPECTED_EVENTS = [ 16427db96d56Sopenharmony_ci (0, 'call'), 16437db96d56Sopenharmony_ci (1, 'line'), 16447db96d56Sopenharmony_ci (2, 'line'), 16457db96d56Sopenharmony_ci (65540, 'line'), 16467db96d56Sopenharmony_ci (65541, 'line'), 16477db96d56Sopenharmony_ci (65541, 'return'), 16487db96d56Sopenharmony_ci ] 16497db96d56Sopenharmony_ci 16507db96d56Sopenharmony_ci self.run_and_compare(f, EXPECTED_EVENTS) 16517db96d56Sopenharmony_ci 16527db96d56Sopenharmony_ci 16537db96d56Sopenharmony_ciEVENT_NAMES = [ 16547db96d56Sopenharmony_ci 'call', 16557db96d56Sopenharmony_ci 'exception', 16567db96d56Sopenharmony_ci 'line', 16577db96d56Sopenharmony_ci 'return' 16587db96d56Sopenharmony_ci] 16597db96d56Sopenharmony_ci 16607db96d56Sopenharmony_ci 16617db96d56Sopenharmony_ciclass SkipLineEventsTraceTestCase(TraceTestCase): 16627db96d56Sopenharmony_ci """Repeat the trace tests, but with per-line events skipped""" 16637db96d56Sopenharmony_ci 16647db96d56Sopenharmony_ci def compare_events(self, line_offset, events, expected_events): 16657db96d56Sopenharmony_ci skip_line_events = [e for e in expected_events if e[1] != 'line'] 16667db96d56Sopenharmony_ci super().compare_events(line_offset, events, skip_line_events) 16677db96d56Sopenharmony_ci 16687db96d56Sopenharmony_ci @staticmethod 16697db96d56Sopenharmony_ci def make_tracer(): 16707db96d56Sopenharmony_ci return Tracer(trace_line_events=False) 16717db96d56Sopenharmony_ci 16727db96d56Sopenharmony_ci 16737db96d56Sopenharmony_ci@support.cpython_only 16747db96d56Sopenharmony_ciclass TraceOpcodesTestCase(TraceTestCase): 16757db96d56Sopenharmony_ci """Repeat the trace tests, but with per-opcodes events enabled""" 16767db96d56Sopenharmony_ci 16777db96d56Sopenharmony_ci def compare_events(self, line_offset, events, expected_events): 16787db96d56Sopenharmony_ci skip_opcode_events = [e for e in events if e[1] != 'opcode'] 16797db96d56Sopenharmony_ci if len(events) > 1: 16807db96d56Sopenharmony_ci self.assertLess(len(skip_opcode_events), len(events), 16817db96d56Sopenharmony_ci msg="No 'opcode' events received by the tracer") 16827db96d56Sopenharmony_ci super().compare_events(line_offset, skip_opcode_events, expected_events) 16837db96d56Sopenharmony_ci 16847db96d56Sopenharmony_ci @staticmethod 16857db96d56Sopenharmony_ci def make_tracer(): 16867db96d56Sopenharmony_ci return Tracer(trace_opcode_events=True) 16877db96d56Sopenharmony_ci 16887db96d56Sopenharmony_ci 16897db96d56Sopenharmony_ciclass RaisingTraceFuncTestCase(unittest.TestCase): 16907db96d56Sopenharmony_ci def setUp(self): 16917db96d56Sopenharmony_ci self.addCleanup(sys.settrace, sys.gettrace()) 16927db96d56Sopenharmony_ci 16937db96d56Sopenharmony_ci def trace(self, frame, event, arg): 16947db96d56Sopenharmony_ci """A trace function that raises an exception in response to a 16957db96d56Sopenharmony_ci specific trace event.""" 16967db96d56Sopenharmony_ci if event == self.raiseOnEvent: 16977db96d56Sopenharmony_ci raise ValueError # just something that isn't RuntimeError 16987db96d56Sopenharmony_ci else: 16997db96d56Sopenharmony_ci return self.trace 17007db96d56Sopenharmony_ci 17017db96d56Sopenharmony_ci def f(self): 17027db96d56Sopenharmony_ci """The function to trace; raises an exception if that's the case 17037db96d56Sopenharmony_ci we're testing, so that the 'exception' trace event fires.""" 17047db96d56Sopenharmony_ci if self.raiseOnEvent == 'exception': 17057db96d56Sopenharmony_ci x = 0 17067db96d56Sopenharmony_ci y = 1/x 17077db96d56Sopenharmony_ci else: 17087db96d56Sopenharmony_ci return 1 17097db96d56Sopenharmony_ci 17107db96d56Sopenharmony_ci def run_test_for_event(self, event): 17117db96d56Sopenharmony_ci """Tests that an exception raised in response to the given event is 17127db96d56Sopenharmony_ci handled OK.""" 17137db96d56Sopenharmony_ci self.raiseOnEvent = event 17147db96d56Sopenharmony_ci try: 17157db96d56Sopenharmony_ci for i in range(sys.getrecursionlimit() + 1): 17167db96d56Sopenharmony_ci sys.settrace(self.trace) 17177db96d56Sopenharmony_ci try: 17187db96d56Sopenharmony_ci self.f() 17197db96d56Sopenharmony_ci except ValueError: 17207db96d56Sopenharmony_ci pass 17217db96d56Sopenharmony_ci else: 17227db96d56Sopenharmony_ci self.fail("exception not raised!") 17237db96d56Sopenharmony_ci except RuntimeError: 17247db96d56Sopenharmony_ci self.fail("recursion counter not reset") 17257db96d56Sopenharmony_ci 17267db96d56Sopenharmony_ci # Test the handling of exceptions raised by each kind of trace event. 17277db96d56Sopenharmony_ci def test_call(self): 17287db96d56Sopenharmony_ci self.run_test_for_event('call') 17297db96d56Sopenharmony_ci def test_line(self): 17307db96d56Sopenharmony_ci self.run_test_for_event('line') 17317db96d56Sopenharmony_ci def test_return(self): 17327db96d56Sopenharmony_ci self.run_test_for_event('return') 17337db96d56Sopenharmony_ci def test_exception(self): 17347db96d56Sopenharmony_ci self.run_test_for_event('exception') 17357db96d56Sopenharmony_ci 17367db96d56Sopenharmony_ci def test_trash_stack(self): 17377db96d56Sopenharmony_ci def f(): 17387db96d56Sopenharmony_ci for i in range(5): 17397db96d56Sopenharmony_ci print(i) # line tracing will raise an exception at this line 17407db96d56Sopenharmony_ci 17417db96d56Sopenharmony_ci def g(frame, why, extra): 17427db96d56Sopenharmony_ci if (why == 'line' and 17437db96d56Sopenharmony_ci frame.f_lineno == f.__code__.co_firstlineno + 2): 17447db96d56Sopenharmony_ci raise RuntimeError("i am crashing") 17457db96d56Sopenharmony_ci return g 17467db96d56Sopenharmony_ci 17477db96d56Sopenharmony_ci sys.settrace(g) 17487db96d56Sopenharmony_ci try: 17497db96d56Sopenharmony_ci f() 17507db96d56Sopenharmony_ci except RuntimeError: 17517db96d56Sopenharmony_ci # the test is really that this doesn't segfault: 17527db96d56Sopenharmony_ci import gc 17537db96d56Sopenharmony_ci gc.collect() 17547db96d56Sopenharmony_ci else: 17557db96d56Sopenharmony_ci self.fail("exception not propagated") 17567db96d56Sopenharmony_ci 17577db96d56Sopenharmony_ci 17587db96d56Sopenharmony_ci def test_exception_arguments(self): 17597db96d56Sopenharmony_ci def f(): 17607db96d56Sopenharmony_ci x = 0 17617db96d56Sopenharmony_ci # this should raise an error 17627db96d56Sopenharmony_ci x.no_such_attr 17637db96d56Sopenharmony_ci def g(frame, event, arg): 17647db96d56Sopenharmony_ci if (event == 'exception'): 17657db96d56Sopenharmony_ci type, exception, trace = arg 17667db96d56Sopenharmony_ci self.assertIsInstance(exception, Exception) 17677db96d56Sopenharmony_ci return g 17687db96d56Sopenharmony_ci 17697db96d56Sopenharmony_ci existing = sys.gettrace() 17707db96d56Sopenharmony_ci try: 17717db96d56Sopenharmony_ci sys.settrace(g) 17727db96d56Sopenharmony_ci try: 17737db96d56Sopenharmony_ci f() 17747db96d56Sopenharmony_ci except AttributeError: 17757db96d56Sopenharmony_ci # this is expected 17767db96d56Sopenharmony_ci pass 17777db96d56Sopenharmony_ci finally: 17787db96d56Sopenharmony_ci sys.settrace(existing) 17797db96d56Sopenharmony_ci 17807db96d56Sopenharmony_ci def test_line_event_raises_before_opcode_event(self): 17817db96d56Sopenharmony_ci exception = ValueError("BOOM!") 17827db96d56Sopenharmony_ci def trace(frame, event, arg): 17837db96d56Sopenharmony_ci if event == "line": 17847db96d56Sopenharmony_ci raise exception 17857db96d56Sopenharmony_ci frame.f_trace_opcodes = True 17867db96d56Sopenharmony_ci return trace 17877db96d56Sopenharmony_ci def f(): 17887db96d56Sopenharmony_ci pass 17897db96d56Sopenharmony_ci with self.assertRaises(ValueError) as caught: 17907db96d56Sopenharmony_ci sys.settrace(trace) 17917db96d56Sopenharmony_ci f() 17927db96d56Sopenharmony_ci self.assertIs(caught.exception, exception) 17937db96d56Sopenharmony_ci 17947db96d56Sopenharmony_ci 17957db96d56Sopenharmony_ci# 'Jump' tests: assigning to frame.f_lineno within a trace function 17967db96d56Sopenharmony_ci# moves the execution position - it's how debuggers implement a Jump 17977db96d56Sopenharmony_ci# command (aka. "Set next statement"). 17987db96d56Sopenharmony_ci 17997db96d56Sopenharmony_ciclass JumpTracer: 18007db96d56Sopenharmony_ci """Defines a trace function that jumps from one place to another.""" 18017db96d56Sopenharmony_ci 18027db96d56Sopenharmony_ci def __init__(self, function, jumpFrom, jumpTo, event='line', 18037db96d56Sopenharmony_ci decorated=False): 18047db96d56Sopenharmony_ci self.code = function.__code__ 18057db96d56Sopenharmony_ci self.jumpFrom = jumpFrom 18067db96d56Sopenharmony_ci self.jumpTo = jumpTo 18077db96d56Sopenharmony_ci self.event = event 18087db96d56Sopenharmony_ci self.firstLine = None if decorated else self.code.co_firstlineno 18097db96d56Sopenharmony_ci self.done = False 18107db96d56Sopenharmony_ci 18117db96d56Sopenharmony_ci def trace(self, frame, event, arg): 18127db96d56Sopenharmony_ci if self.done: 18137db96d56Sopenharmony_ci return 18147db96d56Sopenharmony_ci # frame.f_code.co_firstlineno is the first line of the decorator when 18157db96d56Sopenharmony_ci # 'function' is decorated and the decorator may be written using 18167db96d56Sopenharmony_ci # multiple physical lines when it is too long. Use the first line 18177db96d56Sopenharmony_ci # trace event in 'function' to find the first line of 'function'. 18187db96d56Sopenharmony_ci if (self.firstLine is None and frame.f_code == self.code and 18197db96d56Sopenharmony_ci event == 'line'): 18207db96d56Sopenharmony_ci self.firstLine = frame.f_lineno - 1 18217db96d56Sopenharmony_ci if (event == self.event and self.firstLine is not None and 18227db96d56Sopenharmony_ci frame.f_lineno == self.firstLine + self.jumpFrom): 18237db96d56Sopenharmony_ci f = frame 18247db96d56Sopenharmony_ci while f is not None and f.f_code != self.code: 18257db96d56Sopenharmony_ci f = f.f_back 18267db96d56Sopenharmony_ci if f is not None: 18277db96d56Sopenharmony_ci # Cope with non-integer self.jumpTo (because of 18287db96d56Sopenharmony_ci # no_jump_to_non_integers below). 18297db96d56Sopenharmony_ci try: 18307db96d56Sopenharmony_ci frame.f_lineno = self.firstLine + self.jumpTo 18317db96d56Sopenharmony_ci except TypeError: 18327db96d56Sopenharmony_ci frame.f_lineno = self.jumpTo 18337db96d56Sopenharmony_ci self.done = True 18347db96d56Sopenharmony_ci return self.trace 18357db96d56Sopenharmony_ci 18367db96d56Sopenharmony_ci# This verifies the line-numbers-must-be-integers rule. 18377db96d56Sopenharmony_cidef no_jump_to_non_integers(output): 18387db96d56Sopenharmony_ci try: 18397db96d56Sopenharmony_ci output.append(2) 18407db96d56Sopenharmony_ci except ValueError as e: 18417db96d56Sopenharmony_ci output.append('integer' in str(e)) 18427db96d56Sopenharmony_ci 18437db96d56Sopenharmony_ci# This verifies that you can't set f_lineno via _getframe or similar 18447db96d56Sopenharmony_ci# trickery. 18457db96d56Sopenharmony_cidef no_jump_without_trace_function(): 18467db96d56Sopenharmony_ci try: 18477db96d56Sopenharmony_ci previous_frame = sys._getframe().f_back 18487db96d56Sopenharmony_ci previous_frame.f_lineno = previous_frame.f_lineno 18497db96d56Sopenharmony_ci except ValueError as e: 18507db96d56Sopenharmony_ci # This is the exception we wanted; make sure the error message 18517db96d56Sopenharmony_ci # talks about trace functions. 18527db96d56Sopenharmony_ci if 'trace' not in str(e): 18537db96d56Sopenharmony_ci raise 18547db96d56Sopenharmony_ci else: 18557db96d56Sopenharmony_ci # Something's wrong - the expected exception wasn't raised. 18567db96d56Sopenharmony_ci raise AssertionError("Trace-function-less jump failed to fail") 18577db96d56Sopenharmony_ci 18587db96d56Sopenharmony_ci 18597db96d56Sopenharmony_ciclass JumpTestCase(unittest.TestCase): 18607db96d56Sopenharmony_ci def setUp(self): 18617db96d56Sopenharmony_ci self.addCleanup(sys.settrace, sys.gettrace()) 18627db96d56Sopenharmony_ci sys.settrace(None) 18637db96d56Sopenharmony_ci 18647db96d56Sopenharmony_ci def compare_jump_output(self, expected, received): 18657db96d56Sopenharmony_ci if received != expected: 18667db96d56Sopenharmony_ci self.fail( "Outputs don't match:\n" + 18677db96d56Sopenharmony_ci "Expected: " + repr(expected) + "\n" + 18687db96d56Sopenharmony_ci "Received: " + repr(received)) 18697db96d56Sopenharmony_ci 18707db96d56Sopenharmony_ci def run_test(self, func, jumpFrom, jumpTo, expected, error=None, 18717db96d56Sopenharmony_ci event='line', decorated=False): 18727db96d56Sopenharmony_ci tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated) 18737db96d56Sopenharmony_ci sys.settrace(tracer.trace) 18747db96d56Sopenharmony_ci output = [] 18757db96d56Sopenharmony_ci if error is None: 18767db96d56Sopenharmony_ci func(output) 18777db96d56Sopenharmony_ci else: 18787db96d56Sopenharmony_ci with self.assertRaisesRegex(*error): 18797db96d56Sopenharmony_ci func(output) 18807db96d56Sopenharmony_ci sys.settrace(None) 18817db96d56Sopenharmony_ci self.compare_jump_output(expected, output) 18827db96d56Sopenharmony_ci 18837db96d56Sopenharmony_ci def run_async_test(self, func, jumpFrom, jumpTo, expected, error=None, 18847db96d56Sopenharmony_ci event='line', decorated=False): 18857db96d56Sopenharmony_ci tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated) 18867db96d56Sopenharmony_ci sys.settrace(tracer.trace) 18877db96d56Sopenharmony_ci output = [] 18887db96d56Sopenharmony_ci if error is None: 18897db96d56Sopenharmony_ci asyncio.run(func(output)) 18907db96d56Sopenharmony_ci else: 18917db96d56Sopenharmony_ci with self.assertRaisesRegex(*error): 18927db96d56Sopenharmony_ci asyncio.run(func(output)) 18937db96d56Sopenharmony_ci sys.settrace(None) 18947db96d56Sopenharmony_ci asyncio.set_event_loop_policy(None) 18957db96d56Sopenharmony_ci self.compare_jump_output(expected, output) 18967db96d56Sopenharmony_ci 18977db96d56Sopenharmony_ci def jump_test(jumpFrom, jumpTo, expected, error=None, event='line'): 18987db96d56Sopenharmony_ci """Decorator that creates a test that makes a jump 18997db96d56Sopenharmony_ci from one place to another in the following code. 19007db96d56Sopenharmony_ci """ 19017db96d56Sopenharmony_ci def decorator(func): 19027db96d56Sopenharmony_ci @wraps(func) 19037db96d56Sopenharmony_ci def test(self): 19047db96d56Sopenharmony_ci self.run_test(func, jumpFrom, jumpTo, expected, 19057db96d56Sopenharmony_ci error=error, event=event, decorated=True) 19067db96d56Sopenharmony_ci return test 19077db96d56Sopenharmony_ci return decorator 19087db96d56Sopenharmony_ci 19097db96d56Sopenharmony_ci def async_jump_test(jumpFrom, jumpTo, expected, error=None, event='line'): 19107db96d56Sopenharmony_ci """Decorator that creates a test that makes a jump 19117db96d56Sopenharmony_ci from one place to another in the following asynchronous code. 19127db96d56Sopenharmony_ci """ 19137db96d56Sopenharmony_ci def decorator(func): 19147db96d56Sopenharmony_ci @wraps(func) 19157db96d56Sopenharmony_ci def test(self): 19167db96d56Sopenharmony_ci self.run_async_test(func, jumpFrom, jumpTo, expected, 19177db96d56Sopenharmony_ci error=error, event=event, decorated=True) 19187db96d56Sopenharmony_ci return test 19197db96d56Sopenharmony_ci return decorator 19207db96d56Sopenharmony_ci 19217db96d56Sopenharmony_ci ## The first set of 'jump' tests are for things that are allowed: 19227db96d56Sopenharmony_ci 19237db96d56Sopenharmony_ci @jump_test(1, 3, [3]) 19247db96d56Sopenharmony_ci def test_jump_simple_forwards(output): 19257db96d56Sopenharmony_ci output.append(1) 19267db96d56Sopenharmony_ci output.append(2) 19277db96d56Sopenharmony_ci output.append(3) 19287db96d56Sopenharmony_ci 19297db96d56Sopenharmony_ci @jump_test(2, 1, [1, 1, 2]) 19307db96d56Sopenharmony_ci def test_jump_simple_backwards(output): 19317db96d56Sopenharmony_ci output.append(1) 19327db96d56Sopenharmony_ci output.append(2) 19337db96d56Sopenharmony_ci 19347db96d56Sopenharmony_ci @jump_test(3, 5, [2, 5]) 19357db96d56Sopenharmony_ci def test_jump_out_of_block_forwards(output): 19367db96d56Sopenharmony_ci for i in 1, 2: 19377db96d56Sopenharmony_ci output.append(2) 19387db96d56Sopenharmony_ci for j in [3]: # Also tests jumping over a block 19397db96d56Sopenharmony_ci output.append(4) 19407db96d56Sopenharmony_ci output.append(5) 19417db96d56Sopenharmony_ci 19427db96d56Sopenharmony_ci @jump_test(6, 1, [1, 3, 5, 1, 3, 5, 6, 7]) 19437db96d56Sopenharmony_ci def test_jump_out_of_block_backwards(output): 19447db96d56Sopenharmony_ci output.append(1) 19457db96d56Sopenharmony_ci for i in [1]: 19467db96d56Sopenharmony_ci output.append(3) 19477db96d56Sopenharmony_ci for j in [2]: # Also tests jumping over a block 19487db96d56Sopenharmony_ci output.append(5) 19497db96d56Sopenharmony_ci output.append(6) 19507db96d56Sopenharmony_ci output.append(7) 19517db96d56Sopenharmony_ci 19527db96d56Sopenharmony_ci @async_jump_test(4, 5, [3, 5]) 19537db96d56Sopenharmony_ci async def test_jump_out_of_async_for_block_forwards(output): 19547db96d56Sopenharmony_ci for i in [1]: 19557db96d56Sopenharmony_ci async for i in asynciter([1, 2]): 19567db96d56Sopenharmony_ci output.append(3) 19577db96d56Sopenharmony_ci output.append(4) 19587db96d56Sopenharmony_ci output.append(5) 19597db96d56Sopenharmony_ci 19607db96d56Sopenharmony_ci @async_jump_test(5, 2, [2, 4, 2, 4, 5, 6]) 19617db96d56Sopenharmony_ci async def test_jump_out_of_async_for_block_backwards(output): 19627db96d56Sopenharmony_ci for i in [1]: 19637db96d56Sopenharmony_ci output.append(2) 19647db96d56Sopenharmony_ci async for i in asynciter([1]): 19657db96d56Sopenharmony_ci output.append(4) 19667db96d56Sopenharmony_ci output.append(5) 19677db96d56Sopenharmony_ci output.append(6) 19687db96d56Sopenharmony_ci 19697db96d56Sopenharmony_ci @jump_test(1, 2, [3]) 19707db96d56Sopenharmony_ci def test_jump_to_codeless_line(output): 19717db96d56Sopenharmony_ci output.append(1) 19727db96d56Sopenharmony_ci # Jumping to this line should skip to the next one. 19737db96d56Sopenharmony_ci output.append(3) 19747db96d56Sopenharmony_ci 19757db96d56Sopenharmony_ci @jump_test(2, 2, [1, 2, 3]) 19767db96d56Sopenharmony_ci def test_jump_to_same_line(output): 19777db96d56Sopenharmony_ci output.append(1) 19787db96d56Sopenharmony_ci output.append(2) 19797db96d56Sopenharmony_ci output.append(3) 19807db96d56Sopenharmony_ci 19817db96d56Sopenharmony_ci # Tests jumping within a finally block, and over one. 19827db96d56Sopenharmony_ci @jump_test(4, 9, [2, 9]) 19837db96d56Sopenharmony_ci def test_jump_in_nested_finally(output): 19847db96d56Sopenharmony_ci try: 19857db96d56Sopenharmony_ci output.append(2) 19867db96d56Sopenharmony_ci finally: 19877db96d56Sopenharmony_ci output.append(4) 19887db96d56Sopenharmony_ci try: 19897db96d56Sopenharmony_ci output.append(6) 19907db96d56Sopenharmony_ci finally: 19917db96d56Sopenharmony_ci output.append(8) 19927db96d56Sopenharmony_ci output.append(9) 19937db96d56Sopenharmony_ci 19947db96d56Sopenharmony_ci @jump_test(6, 7, [2, 7], (ZeroDivisionError, '')) 19957db96d56Sopenharmony_ci def test_jump_in_nested_finally_2(output): 19967db96d56Sopenharmony_ci try: 19977db96d56Sopenharmony_ci output.append(2) 19987db96d56Sopenharmony_ci 1/0 19997db96d56Sopenharmony_ci return 20007db96d56Sopenharmony_ci finally: 20017db96d56Sopenharmony_ci output.append(6) 20027db96d56Sopenharmony_ci output.append(7) 20037db96d56Sopenharmony_ci output.append(8) 20047db96d56Sopenharmony_ci 20057db96d56Sopenharmony_ci @jump_test(6, 11, [2, 11], (ZeroDivisionError, '')) 20067db96d56Sopenharmony_ci def test_jump_in_nested_finally_3(output): 20077db96d56Sopenharmony_ci try: 20087db96d56Sopenharmony_ci output.append(2) 20097db96d56Sopenharmony_ci 1/0 20107db96d56Sopenharmony_ci return 20117db96d56Sopenharmony_ci finally: 20127db96d56Sopenharmony_ci output.append(6) 20137db96d56Sopenharmony_ci try: 20147db96d56Sopenharmony_ci output.append(8) 20157db96d56Sopenharmony_ci finally: 20167db96d56Sopenharmony_ci output.append(10) 20177db96d56Sopenharmony_ci output.append(11) 20187db96d56Sopenharmony_ci output.append(12) 20197db96d56Sopenharmony_ci 20207db96d56Sopenharmony_ci @jump_test(5, 11, [2, 4], (ValueError, 'exception')) 20217db96d56Sopenharmony_ci def test_no_jump_over_return_try_finally_in_finally_block(output): 20227db96d56Sopenharmony_ci try: 20237db96d56Sopenharmony_ci output.append(2) 20247db96d56Sopenharmony_ci finally: 20257db96d56Sopenharmony_ci output.append(4) 20267db96d56Sopenharmony_ci output.append(5) 20277db96d56Sopenharmony_ci return 20287db96d56Sopenharmony_ci try: 20297db96d56Sopenharmony_ci output.append(8) 20307db96d56Sopenharmony_ci finally: 20317db96d56Sopenharmony_ci output.append(10) 20327db96d56Sopenharmony_ci pass 20337db96d56Sopenharmony_ci output.append(12) 20347db96d56Sopenharmony_ci 20357db96d56Sopenharmony_ci @jump_test(3, 4, [1], (ValueError, 'after')) 20367db96d56Sopenharmony_ci def test_no_jump_infinite_while_loop(output): 20377db96d56Sopenharmony_ci output.append(1) 20387db96d56Sopenharmony_ci while True: 20397db96d56Sopenharmony_ci output.append(3) 20407db96d56Sopenharmony_ci output.append(4) 20417db96d56Sopenharmony_ci 20427db96d56Sopenharmony_ci @jump_test(2, 4, [4, 4]) 20437db96d56Sopenharmony_ci def test_jump_forwards_into_while_block(output): 20447db96d56Sopenharmony_ci i = 1 20457db96d56Sopenharmony_ci output.append(2) 20467db96d56Sopenharmony_ci while i <= 2: 20477db96d56Sopenharmony_ci output.append(4) 20487db96d56Sopenharmony_ci i += 1 20497db96d56Sopenharmony_ci 20507db96d56Sopenharmony_ci @jump_test(5, 3, [3, 3, 3, 5]) 20517db96d56Sopenharmony_ci def test_jump_backwards_into_while_block(output): 20527db96d56Sopenharmony_ci i = 1 20537db96d56Sopenharmony_ci while i <= 2: 20547db96d56Sopenharmony_ci output.append(3) 20557db96d56Sopenharmony_ci i += 1 20567db96d56Sopenharmony_ci output.append(5) 20577db96d56Sopenharmony_ci 20587db96d56Sopenharmony_ci @jump_test(2, 3, [1, 3]) 20597db96d56Sopenharmony_ci def test_jump_forwards_out_of_with_block(output): 20607db96d56Sopenharmony_ci with tracecontext(output, 1): 20617db96d56Sopenharmony_ci output.append(2) 20627db96d56Sopenharmony_ci output.append(3) 20637db96d56Sopenharmony_ci 20647db96d56Sopenharmony_ci @async_jump_test(2, 3, [1, 3]) 20657db96d56Sopenharmony_ci async def test_jump_forwards_out_of_async_with_block(output): 20667db96d56Sopenharmony_ci async with asynctracecontext(output, 1): 20677db96d56Sopenharmony_ci output.append(2) 20687db96d56Sopenharmony_ci output.append(3) 20697db96d56Sopenharmony_ci 20707db96d56Sopenharmony_ci @jump_test(3, 1, [1, 2, 1, 2, 3, -2]) 20717db96d56Sopenharmony_ci def test_jump_backwards_out_of_with_block(output): 20727db96d56Sopenharmony_ci output.append(1) 20737db96d56Sopenharmony_ci with tracecontext(output, 2): 20747db96d56Sopenharmony_ci output.append(3) 20757db96d56Sopenharmony_ci 20767db96d56Sopenharmony_ci @async_jump_test(3, 1, [1, 2, 1, 2, 3, -2]) 20777db96d56Sopenharmony_ci async def test_jump_backwards_out_of_async_with_block(output): 20787db96d56Sopenharmony_ci output.append(1) 20797db96d56Sopenharmony_ci async with asynctracecontext(output, 2): 20807db96d56Sopenharmony_ci output.append(3) 20817db96d56Sopenharmony_ci 20827db96d56Sopenharmony_ci @jump_test(2, 5, [5]) 20837db96d56Sopenharmony_ci def test_jump_forwards_out_of_try_finally_block(output): 20847db96d56Sopenharmony_ci try: 20857db96d56Sopenharmony_ci output.append(2) 20867db96d56Sopenharmony_ci finally: 20877db96d56Sopenharmony_ci output.append(4) 20887db96d56Sopenharmony_ci output.append(5) 20897db96d56Sopenharmony_ci 20907db96d56Sopenharmony_ci @jump_test(3, 1, [1, 1, 3, 5]) 20917db96d56Sopenharmony_ci def test_jump_backwards_out_of_try_finally_block(output): 20927db96d56Sopenharmony_ci output.append(1) 20937db96d56Sopenharmony_ci try: 20947db96d56Sopenharmony_ci output.append(3) 20957db96d56Sopenharmony_ci finally: 20967db96d56Sopenharmony_ci output.append(5) 20977db96d56Sopenharmony_ci 20987db96d56Sopenharmony_ci @jump_test(2, 6, [6]) 20997db96d56Sopenharmony_ci def test_jump_forwards_out_of_try_except_block(output): 21007db96d56Sopenharmony_ci try: 21017db96d56Sopenharmony_ci output.append(2) 21027db96d56Sopenharmony_ci except: 21037db96d56Sopenharmony_ci output.append(4) 21047db96d56Sopenharmony_ci raise 21057db96d56Sopenharmony_ci output.append(6) 21067db96d56Sopenharmony_ci 21077db96d56Sopenharmony_ci @jump_test(3, 1, [1, 1, 3]) 21087db96d56Sopenharmony_ci def test_jump_backwards_out_of_try_except_block(output): 21097db96d56Sopenharmony_ci output.append(1) 21107db96d56Sopenharmony_ci try: 21117db96d56Sopenharmony_ci output.append(3) 21127db96d56Sopenharmony_ci except: 21137db96d56Sopenharmony_ci output.append(5) 21147db96d56Sopenharmony_ci raise 21157db96d56Sopenharmony_ci 21167db96d56Sopenharmony_ci @jump_test(5, 7, [4, 7, 8]) 21177db96d56Sopenharmony_ci def test_jump_between_except_blocks(output): 21187db96d56Sopenharmony_ci try: 21197db96d56Sopenharmony_ci 1/0 21207db96d56Sopenharmony_ci except ZeroDivisionError: 21217db96d56Sopenharmony_ci output.append(4) 21227db96d56Sopenharmony_ci output.append(5) 21237db96d56Sopenharmony_ci except FloatingPointError: 21247db96d56Sopenharmony_ci output.append(7) 21257db96d56Sopenharmony_ci output.append(8) 21267db96d56Sopenharmony_ci 21277db96d56Sopenharmony_ci @jump_test(5, 7, [4, 7, 8]) 21287db96d56Sopenharmony_ci def test_jump_from_except_to_finally(output): 21297db96d56Sopenharmony_ci try: 21307db96d56Sopenharmony_ci 1/0 21317db96d56Sopenharmony_ci except ZeroDivisionError: 21327db96d56Sopenharmony_ci output.append(4) 21337db96d56Sopenharmony_ci output.append(5) 21347db96d56Sopenharmony_ci finally: 21357db96d56Sopenharmony_ci output.append(7) 21367db96d56Sopenharmony_ci output.append(8) 21377db96d56Sopenharmony_ci 21387db96d56Sopenharmony_ci @jump_test(5, 6, [4, 6, 7]) 21397db96d56Sopenharmony_ci def test_jump_within_except_block(output): 21407db96d56Sopenharmony_ci try: 21417db96d56Sopenharmony_ci 1/0 21427db96d56Sopenharmony_ci except: 21437db96d56Sopenharmony_ci output.append(4) 21447db96d56Sopenharmony_ci output.append(5) 21457db96d56Sopenharmony_ci output.append(6) 21467db96d56Sopenharmony_ci output.append(7) 21477db96d56Sopenharmony_ci 21487db96d56Sopenharmony_ci @jump_test(6, 1, [1, 5, 1, 5]) 21497db96d56Sopenharmony_ci def test_jump_over_try_except(output): 21507db96d56Sopenharmony_ci output.append(1) 21517db96d56Sopenharmony_ci try: 21527db96d56Sopenharmony_ci 1 / 0 21537db96d56Sopenharmony_ci except ZeroDivisionError as e: 21547db96d56Sopenharmony_ci output.append(5) 21557db96d56Sopenharmony_ci x = 42 # has to be a two-instruction block 21567db96d56Sopenharmony_ci 21577db96d56Sopenharmony_ci @jump_test(2, 4, [1, 4, 5, -4]) 21587db96d56Sopenharmony_ci def test_jump_across_with(output): 21597db96d56Sopenharmony_ci output.append(1) 21607db96d56Sopenharmony_ci with tracecontext(output, 2): 21617db96d56Sopenharmony_ci output.append(3) 21627db96d56Sopenharmony_ci with tracecontext(output, 4): 21637db96d56Sopenharmony_ci output.append(5) 21647db96d56Sopenharmony_ci 21657db96d56Sopenharmony_ci @async_jump_test(2, 4, [1, 4, 5, -4]) 21667db96d56Sopenharmony_ci async def test_jump_across_async_with(output): 21677db96d56Sopenharmony_ci output.append(1) 21687db96d56Sopenharmony_ci async with asynctracecontext(output, 2): 21697db96d56Sopenharmony_ci output.append(3) 21707db96d56Sopenharmony_ci async with asynctracecontext(output, 4): 21717db96d56Sopenharmony_ci output.append(5) 21727db96d56Sopenharmony_ci 21737db96d56Sopenharmony_ci @jump_test(4, 5, [1, 3, 5, 6]) 21747db96d56Sopenharmony_ci def test_jump_out_of_with_block_within_for_block(output): 21757db96d56Sopenharmony_ci output.append(1) 21767db96d56Sopenharmony_ci for i in [1]: 21777db96d56Sopenharmony_ci with tracecontext(output, 3): 21787db96d56Sopenharmony_ci output.append(4) 21797db96d56Sopenharmony_ci output.append(5) 21807db96d56Sopenharmony_ci output.append(6) 21817db96d56Sopenharmony_ci 21827db96d56Sopenharmony_ci @async_jump_test(4, 5, [1, 3, 5, 6]) 21837db96d56Sopenharmony_ci async def test_jump_out_of_async_with_block_within_for_block(output): 21847db96d56Sopenharmony_ci output.append(1) 21857db96d56Sopenharmony_ci for i in [1]: 21867db96d56Sopenharmony_ci async with asynctracecontext(output, 3): 21877db96d56Sopenharmony_ci output.append(4) 21887db96d56Sopenharmony_ci output.append(5) 21897db96d56Sopenharmony_ci output.append(6) 21907db96d56Sopenharmony_ci 21917db96d56Sopenharmony_ci @jump_test(4, 5, [1, 2, 3, 5, -2, 6]) 21927db96d56Sopenharmony_ci def test_jump_out_of_with_block_within_with_block(output): 21937db96d56Sopenharmony_ci output.append(1) 21947db96d56Sopenharmony_ci with tracecontext(output, 2): 21957db96d56Sopenharmony_ci with tracecontext(output, 3): 21967db96d56Sopenharmony_ci output.append(4) 21977db96d56Sopenharmony_ci output.append(5) 21987db96d56Sopenharmony_ci output.append(6) 21997db96d56Sopenharmony_ci 22007db96d56Sopenharmony_ci @async_jump_test(4, 5, [1, 2, 3, 5, -2, 6]) 22017db96d56Sopenharmony_ci async def test_jump_out_of_async_with_block_within_with_block(output): 22027db96d56Sopenharmony_ci output.append(1) 22037db96d56Sopenharmony_ci with tracecontext(output, 2): 22047db96d56Sopenharmony_ci async with asynctracecontext(output, 3): 22057db96d56Sopenharmony_ci output.append(4) 22067db96d56Sopenharmony_ci output.append(5) 22077db96d56Sopenharmony_ci output.append(6) 22087db96d56Sopenharmony_ci 22097db96d56Sopenharmony_ci @jump_test(5, 6, [2, 4, 6, 7]) 22107db96d56Sopenharmony_ci def test_jump_out_of_with_block_within_finally_block(output): 22117db96d56Sopenharmony_ci try: 22127db96d56Sopenharmony_ci output.append(2) 22137db96d56Sopenharmony_ci finally: 22147db96d56Sopenharmony_ci with tracecontext(output, 4): 22157db96d56Sopenharmony_ci output.append(5) 22167db96d56Sopenharmony_ci output.append(6) 22177db96d56Sopenharmony_ci output.append(7) 22187db96d56Sopenharmony_ci 22197db96d56Sopenharmony_ci @async_jump_test(5, 6, [2, 4, 6, 7]) 22207db96d56Sopenharmony_ci async def test_jump_out_of_async_with_block_within_finally_block(output): 22217db96d56Sopenharmony_ci try: 22227db96d56Sopenharmony_ci output.append(2) 22237db96d56Sopenharmony_ci finally: 22247db96d56Sopenharmony_ci async with asynctracecontext(output, 4): 22257db96d56Sopenharmony_ci output.append(5) 22267db96d56Sopenharmony_ci output.append(6) 22277db96d56Sopenharmony_ci output.append(7) 22287db96d56Sopenharmony_ci 22297db96d56Sopenharmony_ci @jump_test(8, 11, [1, 3, 5, 11, 12]) 22307db96d56Sopenharmony_ci def test_jump_out_of_complex_nested_blocks(output): 22317db96d56Sopenharmony_ci output.append(1) 22327db96d56Sopenharmony_ci for i in [1]: 22337db96d56Sopenharmony_ci output.append(3) 22347db96d56Sopenharmony_ci for j in [1, 2]: 22357db96d56Sopenharmony_ci output.append(5) 22367db96d56Sopenharmony_ci try: 22377db96d56Sopenharmony_ci for k in [1, 2]: 22387db96d56Sopenharmony_ci output.append(8) 22397db96d56Sopenharmony_ci finally: 22407db96d56Sopenharmony_ci output.append(10) 22417db96d56Sopenharmony_ci output.append(11) 22427db96d56Sopenharmony_ci output.append(12) 22437db96d56Sopenharmony_ci 22447db96d56Sopenharmony_ci @jump_test(3, 5, [1, 2, 5]) 22457db96d56Sopenharmony_ci def test_jump_out_of_with_assignment(output): 22467db96d56Sopenharmony_ci output.append(1) 22477db96d56Sopenharmony_ci with tracecontext(output, 2) \ 22487db96d56Sopenharmony_ci as x: 22497db96d56Sopenharmony_ci output.append(4) 22507db96d56Sopenharmony_ci output.append(5) 22517db96d56Sopenharmony_ci 22527db96d56Sopenharmony_ci @async_jump_test(3, 5, [1, 2, 5]) 22537db96d56Sopenharmony_ci async def test_jump_out_of_async_with_assignment(output): 22547db96d56Sopenharmony_ci output.append(1) 22557db96d56Sopenharmony_ci async with asynctracecontext(output, 2) \ 22567db96d56Sopenharmony_ci as x: 22577db96d56Sopenharmony_ci output.append(4) 22587db96d56Sopenharmony_ci output.append(5) 22597db96d56Sopenharmony_ci 22607db96d56Sopenharmony_ci @jump_test(3, 6, [1, 6, 8, 9]) 22617db96d56Sopenharmony_ci def test_jump_over_return_in_try_finally_block(output): 22627db96d56Sopenharmony_ci output.append(1) 22637db96d56Sopenharmony_ci try: 22647db96d56Sopenharmony_ci output.append(3) 22657db96d56Sopenharmony_ci if not output: # always false 22667db96d56Sopenharmony_ci return 22677db96d56Sopenharmony_ci output.append(6) 22687db96d56Sopenharmony_ci finally: 22697db96d56Sopenharmony_ci output.append(8) 22707db96d56Sopenharmony_ci output.append(9) 22717db96d56Sopenharmony_ci 22727db96d56Sopenharmony_ci @jump_test(5, 8, [1, 3, 8, 10, 11, 13]) 22737db96d56Sopenharmony_ci def test_jump_over_break_in_try_finally_block(output): 22747db96d56Sopenharmony_ci output.append(1) 22757db96d56Sopenharmony_ci while True: 22767db96d56Sopenharmony_ci output.append(3) 22777db96d56Sopenharmony_ci try: 22787db96d56Sopenharmony_ci output.append(5) 22797db96d56Sopenharmony_ci if not output: # always false 22807db96d56Sopenharmony_ci break 22817db96d56Sopenharmony_ci output.append(8) 22827db96d56Sopenharmony_ci finally: 22837db96d56Sopenharmony_ci output.append(10) 22847db96d56Sopenharmony_ci output.append(11) 22857db96d56Sopenharmony_ci break 22867db96d56Sopenharmony_ci output.append(13) 22877db96d56Sopenharmony_ci 22887db96d56Sopenharmony_ci @jump_test(1, 7, [7, 8]) 22897db96d56Sopenharmony_ci def test_jump_over_for_block_before_else(output): 22907db96d56Sopenharmony_ci output.append(1) 22917db96d56Sopenharmony_ci if not output: # always false 22927db96d56Sopenharmony_ci for i in [3]: 22937db96d56Sopenharmony_ci output.append(4) 22947db96d56Sopenharmony_ci else: 22957db96d56Sopenharmony_ci output.append(6) 22967db96d56Sopenharmony_ci output.append(7) 22977db96d56Sopenharmony_ci output.append(8) 22987db96d56Sopenharmony_ci 22997db96d56Sopenharmony_ci @async_jump_test(1, 7, [7, 8]) 23007db96d56Sopenharmony_ci async def test_jump_over_async_for_block_before_else(output): 23017db96d56Sopenharmony_ci output.append(1) 23027db96d56Sopenharmony_ci if not output: # always false 23037db96d56Sopenharmony_ci async for i in asynciter([3]): 23047db96d56Sopenharmony_ci output.append(4) 23057db96d56Sopenharmony_ci else: 23067db96d56Sopenharmony_ci output.append(6) 23077db96d56Sopenharmony_ci output.append(7) 23087db96d56Sopenharmony_ci output.append(8) 23097db96d56Sopenharmony_ci 23107db96d56Sopenharmony_ci # The second set of 'jump' tests are for things that are not allowed: 23117db96d56Sopenharmony_ci 23127db96d56Sopenharmony_ci @jump_test(2, 3, [1], (ValueError, 'after')) 23137db96d56Sopenharmony_ci def test_no_jump_too_far_forwards(output): 23147db96d56Sopenharmony_ci output.append(1) 23157db96d56Sopenharmony_ci output.append(2) 23167db96d56Sopenharmony_ci 23177db96d56Sopenharmony_ci @jump_test(2, -2, [1], (ValueError, 'before')) 23187db96d56Sopenharmony_ci def test_no_jump_too_far_backwards(output): 23197db96d56Sopenharmony_ci output.append(1) 23207db96d56Sopenharmony_ci output.append(2) 23217db96d56Sopenharmony_ci 23227db96d56Sopenharmony_ci # Test each kind of 'except' line. 23237db96d56Sopenharmony_ci @jump_test(2, 3, [4], (ValueError, 'except')) 23247db96d56Sopenharmony_ci def test_no_jump_to_except_1(output): 23257db96d56Sopenharmony_ci try: 23267db96d56Sopenharmony_ci output.append(2) 23277db96d56Sopenharmony_ci except: 23287db96d56Sopenharmony_ci output.append(4) 23297db96d56Sopenharmony_ci raise 23307db96d56Sopenharmony_ci 23317db96d56Sopenharmony_ci @jump_test(2, 3, [4], (ValueError, 'except')) 23327db96d56Sopenharmony_ci def test_no_jump_to_except_2(output): 23337db96d56Sopenharmony_ci try: 23347db96d56Sopenharmony_ci output.append(2) 23357db96d56Sopenharmony_ci except ValueError: 23367db96d56Sopenharmony_ci output.append(4) 23377db96d56Sopenharmony_ci raise 23387db96d56Sopenharmony_ci 23397db96d56Sopenharmony_ci @jump_test(2, 3, [4], (ValueError, 'except')) 23407db96d56Sopenharmony_ci def test_no_jump_to_except_3(output): 23417db96d56Sopenharmony_ci try: 23427db96d56Sopenharmony_ci output.append(2) 23437db96d56Sopenharmony_ci except ValueError as e: 23447db96d56Sopenharmony_ci output.append(4) 23457db96d56Sopenharmony_ci raise e 23467db96d56Sopenharmony_ci 23477db96d56Sopenharmony_ci @jump_test(2, 3, [4], (ValueError, 'except')) 23487db96d56Sopenharmony_ci def test_no_jump_to_except_4(output): 23497db96d56Sopenharmony_ci try: 23507db96d56Sopenharmony_ci output.append(2) 23517db96d56Sopenharmony_ci except (ValueError, RuntimeError) as e: 23527db96d56Sopenharmony_ci output.append(4) 23537db96d56Sopenharmony_ci raise e 23547db96d56Sopenharmony_ci 23557db96d56Sopenharmony_ci @jump_test(1, 3, [], (ValueError, 'into')) 23567db96d56Sopenharmony_ci def test_no_jump_forwards_into_for_block(output): 23577db96d56Sopenharmony_ci output.append(1) 23587db96d56Sopenharmony_ci for i in 1, 2: 23597db96d56Sopenharmony_ci output.append(3) 23607db96d56Sopenharmony_ci 23617db96d56Sopenharmony_ci @async_jump_test(1, 3, [], (ValueError, 'into')) 23627db96d56Sopenharmony_ci async def test_no_jump_forwards_into_async_for_block(output): 23637db96d56Sopenharmony_ci output.append(1) 23647db96d56Sopenharmony_ci async for i in asynciter([1, 2]): 23657db96d56Sopenharmony_ci output.append(3) 23667db96d56Sopenharmony_ci pass 23677db96d56Sopenharmony_ci 23687db96d56Sopenharmony_ci @jump_test(3, 2, [2, 2], (ValueError, 'into')) 23697db96d56Sopenharmony_ci def test_no_jump_backwards_into_for_block(output): 23707db96d56Sopenharmony_ci for i in 1, 2: 23717db96d56Sopenharmony_ci output.append(2) 23727db96d56Sopenharmony_ci output.append(3) 23737db96d56Sopenharmony_ci 23747db96d56Sopenharmony_ci @async_jump_test(3, 2, [2, 2], (ValueError, "can't jump into the body of a for loop")) 23757db96d56Sopenharmony_ci async def test_no_jump_backwards_into_async_for_block(output): 23767db96d56Sopenharmony_ci async for i in asynciter([1, 2]): 23777db96d56Sopenharmony_ci output.append(2) 23787db96d56Sopenharmony_ci output.append(3) 23797db96d56Sopenharmony_ci 23807db96d56Sopenharmony_ci @jump_test(1, 3, [], (ValueError, 'stack')) 23817db96d56Sopenharmony_ci def test_no_jump_forwards_into_with_block(output): 23827db96d56Sopenharmony_ci output.append(1) 23837db96d56Sopenharmony_ci with tracecontext(output, 2): 23847db96d56Sopenharmony_ci output.append(3) 23857db96d56Sopenharmony_ci 23867db96d56Sopenharmony_ci @async_jump_test(1, 3, [], (ValueError, 'stack')) 23877db96d56Sopenharmony_ci async def test_no_jump_forwards_into_async_with_block(output): 23887db96d56Sopenharmony_ci output.append(1) 23897db96d56Sopenharmony_ci async with asynctracecontext(output, 2): 23907db96d56Sopenharmony_ci output.append(3) 23917db96d56Sopenharmony_ci 23927db96d56Sopenharmony_ci @jump_test(3, 2, [1, 2, -1], (ValueError, 'stack')) 23937db96d56Sopenharmony_ci def test_no_jump_backwards_into_with_block(output): 23947db96d56Sopenharmony_ci with tracecontext(output, 1): 23957db96d56Sopenharmony_ci output.append(2) 23967db96d56Sopenharmony_ci output.append(3) 23977db96d56Sopenharmony_ci 23987db96d56Sopenharmony_ci @async_jump_test(3, 2, [1, 2, -1], (ValueError, 'stack')) 23997db96d56Sopenharmony_ci async def test_no_jump_backwards_into_async_with_block(output): 24007db96d56Sopenharmony_ci async with asynctracecontext(output, 1): 24017db96d56Sopenharmony_ci output.append(2) 24027db96d56Sopenharmony_ci output.append(3) 24037db96d56Sopenharmony_ci 24047db96d56Sopenharmony_ci @jump_test(1, 3, [3, 5]) 24057db96d56Sopenharmony_ci def test_jump_forwards_into_try_finally_block(output): 24067db96d56Sopenharmony_ci output.append(1) 24077db96d56Sopenharmony_ci try: 24087db96d56Sopenharmony_ci output.append(3) 24097db96d56Sopenharmony_ci finally: 24107db96d56Sopenharmony_ci output.append(5) 24117db96d56Sopenharmony_ci 24127db96d56Sopenharmony_ci @jump_test(5, 2, [2, 4, 2, 4, 5]) 24137db96d56Sopenharmony_ci def test_jump_backwards_into_try_finally_block(output): 24147db96d56Sopenharmony_ci try: 24157db96d56Sopenharmony_ci output.append(2) 24167db96d56Sopenharmony_ci finally: 24177db96d56Sopenharmony_ci output.append(4) 24187db96d56Sopenharmony_ci output.append(5) 24197db96d56Sopenharmony_ci 24207db96d56Sopenharmony_ci @jump_test(1, 3, [3]) 24217db96d56Sopenharmony_ci def test_jump_forwards_into_try_except_block(output): 24227db96d56Sopenharmony_ci output.append(1) 24237db96d56Sopenharmony_ci try: 24247db96d56Sopenharmony_ci output.append(3) 24257db96d56Sopenharmony_ci except: 24267db96d56Sopenharmony_ci output.append(5) 24277db96d56Sopenharmony_ci raise 24287db96d56Sopenharmony_ci 24297db96d56Sopenharmony_ci @jump_test(6, 2, [2, 2, 6]) 24307db96d56Sopenharmony_ci def test_jump_backwards_into_try_except_block(output): 24317db96d56Sopenharmony_ci try: 24327db96d56Sopenharmony_ci output.append(2) 24337db96d56Sopenharmony_ci except: 24347db96d56Sopenharmony_ci output.append(4) 24357db96d56Sopenharmony_ci raise 24367db96d56Sopenharmony_ci output.append(6) 24377db96d56Sopenharmony_ci 24387db96d56Sopenharmony_ci # 'except' with a variable creates an implicit finally block 24397db96d56Sopenharmony_ci @jump_test(5, 7, [4, 7, 8]) 24407db96d56Sopenharmony_ci def test_jump_between_except_blocks_2(output): 24417db96d56Sopenharmony_ci try: 24427db96d56Sopenharmony_ci 1/0 24437db96d56Sopenharmony_ci except ZeroDivisionError: 24447db96d56Sopenharmony_ci output.append(4) 24457db96d56Sopenharmony_ci output.append(5) 24467db96d56Sopenharmony_ci except FloatingPointError as e: 24477db96d56Sopenharmony_ci output.append(7) 24487db96d56Sopenharmony_ci output.append(8) 24497db96d56Sopenharmony_ci 24507db96d56Sopenharmony_ci @jump_test(1, 5, [5]) 24517db96d56Sopenharmony_ci def test_jump_into_finally_block(output): 24527db96d56Sopenharmony_ci output.append(1) 24537db96d56Sopenharmony_ci try: 24547db96d56Sopenharmony_ci output.append(3) 24557db96d56Sopenharmony_ci finally: 24567db96d56Sopenharmony_ci output.append(5) 24577db96d56Sopenharmony_ci 24587db96d56Sopenharmony_ci @jump_test(3, 6, [2, 6, 7]) 24597db96d56Sopenharmony_ci def test_jump_into_finally_block_from_try_block(output): 24607db96d56Sopenharmony_ci try: 24617db96d56Sopenharmony_ci output.append(2) 24627db96d56Sopenharmony_ci output.append(3) 24637db96d56Sopenharmony_ci finally: # still executed if the jump is failed 24647db96d56Sopenharmony_ci output.append(5) 24657db96d56Sopenharmony_ci output.append(6) 24667db96d56Sopenharmony_ci output.append(7) 24677db96d56Sopenharmony_ci 24687db96d56Sopenharmony_ci @jump_test(5, 1, [1, 3, 1, 3, 5]) 24697db96d56Sopenharmony_ci def test_jump_out_of_finally_block(output): 24707db96d56Sopenharmony_ci output.append(1) 24717db96d56Sopenharmony_ci try: 24727db96d56Sopenharmony_ci output.append(3) 24737db96d56Sopenharmony_ci finally: 24747db96d56Sopenharmony_ci output.append(5) 24757db96d56Sopenharmony_ci 24767db96d56Sopenharmony_ci @jump_test(1, 5, [], (ValueError, "can't jump into an 'except' block as there's no exception")) 24777db96d56Sopenharmony_ci def test_no_jump_into_bare_except_block(output): 24787db96d56Sopenharmony_ci output.append(1) 24797db96d56Sopenharmony_ci try: 24807db96d56Sopenharmony_ci output.append(3) 24817db96d56Sopenharmony_ci except: 24827db96d56Sopenharmony_ci output.append(5) 24837db96d56Sopenharmony_ci 24847db96d56Sopenharmony_ci @jump_test(1, 5, [], (ValueError, "can't jump into an 'except' block as there's no exception")) 24857db96d56Sopenharmony_ci def test_no_jump_into_qualified_except_block(output): 24867db96d56Sopenharmony_ci output.append(1) 24877db96d56Sopenharmony_ci try: 24887db96d56Sopenharmony_ci output.append(3) 24897db96d56Sopenharmony_ci except Exception: 24907db96d56Sopenharmony_ci output.append(5) 24917db96d56Sopenharmony_ci 24927db96d56Sopenharmony_ci @jump_test(3, 6, [2, 5, 6], (ValueError, "can't jump into an 'except' block as there's no exception")) 24937db96d56Sopenharmony_ci def test_no_jump_into_bare_except_block_from_try_block(output): 24947db96d56Sopenharmony_ci try: 24957db96d56Sopenharmony_ci output.append(2) 24967db96d56Sopenharmony_ci output.append(3) 24977db96d56Sopenharmony_ci except: # executed if the jump is failed 24987db96d56Sopenharmony_ci output.append(5) 24997db96d56Sopenharmony_ci output.append(6) 25007db96d56Sopenharmony_ci raise 25017db96d56Sopenharmony_ci output.append(8) 25027db96d56Sopenharmony_ci 25037db96d56Sopenharmony_ci @jump_test(3, 6, [2], (ValueError, "can't jump into an 'except' block as there's no exception")) 25047db96d56Sopenharmony_ci def test_no_jump_into_qualified_except_block_from_try_block(output): 25057db96d56Sopenharmony_ci try: 25067db96d56Sopenharmony_ci output.append(2) 25077db96d56Sopenharmony_ci output.append(3) 25087db96d56Sopenharmony_ci except ZeroDivisionError: 25097db96d56Sopenharmony_ci output.append(5) 25107db96d56Sopenharmony_ci output.append(6) 25117db96d56Sopenharmony_ci raise 25127db96d56Sopenharmony_ci output.append(8) 25137db96d56Sopenharmony_ci 25147db96d56Sopenharmony_ci @jump_test(7, 1, [1, 3, 6, 1, 3, 6, 7]) 25157db96d56Sopenharmony_ci def test_jump_out_of_bare_except_block(output): 25167db96d56Sopenharmony_ci output.append(1) 25177db96d56Sopenharmony_ci try: 25187db96d56Sopenharmony_ci output.append(3) 25197db96d56Sopenharmony_ci 1/0 25207db96d56Sopenharmony_ci except: 25217db96d56Sopenharmony_ci output.append(6) 25227db96d56Sopenharmony_ci output.append(7) 25237db96d56Sopenharmony_ci 25247db96d56Sopenharmony_ci @jump_test(7, 1, [1, 3, 6, 1, 3, 6, 7]) 25257db96d56Sopenharmony_ci def test_jump_out_of_qualified_except_block(output): 25267db96d56Sopenharmony_ci output.append(1) 25277db96d56Sopenharmony_ci try: 25287db96d56Sopenharmony_ci output.append(3) 25297db96d56Sopenharmony_ci 1/0 25307db96d56Sopenharmony_ci except Exception: 25317db96d56Sopenharmony_ci output.append(6) 25327db96d56Sopenharmony_ci output.append(7) 25337db96d56Sopenharmony_ci 25347db96d56Sopenharmony_ci @jump_test(3, 5, [1, 2, 5, -2]) 25357db96d56Sopenharmony_ci def test_jump_between_with_blocks(output): 25367db96d56Sopenharmony_ci output.append(1) 25377db96d56Sopenharmony_ci with tracecontext(output, 2): 25387db96d56Sopenharmony_ci output.append(3) 25397db96d56Sopenharmony_ci with tracecontext(output, 4): 25407db96d56Sopenharmony_ci output.append(5) 25417db96d56Sopenharmony_ci 25427db96d56Sopenharmony_ci @async_jump_test(3, 5, [1, 2, 5, -2]) 25437db96d56Sopenharmony_ci async def test_jump_between_async_with_blocks(output): 25447db96d56Sopenharmony_ci output.append(1) 25457db96d56Sopenharmony_ci async with asynctracecontext(output, 2): 25467db96d56Sopenharmony_ci output.append(3) 25477db96d56Sopenharmony_ci async with asynctracecontext(output, 4): 25487db96d56Sopenharmony_ci output.append(5) 25497db96d56Sopenharmony_ci 25507db96d56Sopenharmony_ci @jump_test(5, 7, [2, 4], (ValueError, "after")) 25517db96d56Sopenharmony_ci def test_no_jump_over_return_out_of_finally_block(output): 25527db96d56Sopenharmony_ci try: 25537db96d56Sopenharmony_ci output.append(2) 25547db96d56Sopenharmony_ci finally: 25557db96d56Sopenharmony_ci output.append(4) 25567db96d56Sopenharmony_ci output.append(5) 25577db96d56Sopenharmony_ci return 25587db96d56Sopenharmony_ci output.append(7) 25597db96d56Sopenharmony_ci 25607db96d56Sopenharmony_ci @jump_test(7, 4, [1, 6], (ValueError, 'into')) 25617db96d56Sopenharmony_ci def test_no_jump_into_for_block_before_else(output): 25627db96d56Sopenharmony_ci output.append(1) 25637db96d56Sopenharmony_ci if not output: # always false 25647db96d56Sopenharmony_ci for i in [3]: 25657db96d56Sopenharmony_ci output.append(4) 25667db96d56Sopenharmony_ci else: 25677db96d56Sopenharmony_ci output.append(6) 25687db96d56Sopenharmony_ci output.append(7) 25697db96d56Sopenharmony_ci output.append(8) 25707db96d56Sopenharmony_ci 25717db96d56Sopenharmony_ci @async_jump_test(7, 4, [1, 6], (ValueError, 'into')) 25727db96d56Sopenharmony_ci async def test_no_jump_into_async_for_block_before_else(output): 25737db96d56Sopenharmony_ci output.append(1) 25747db96d56Sopenharmony_ci if not output: # always false 25757db96d56Sopenharmony_ci async for i in asynciter([3]): 25767db96d56Sopenharmony_ci output.append(4) 25777db96d56Sopenharmony_ci else: 25787db96d56Sopenharmony_ci output.append(6) 25797db96d56Sopenharmony_ci output.append(7) 25807db96d56Sopenharmony_ci output.append(8) 25817db96d56Sopenharmony_ci 25827db96d56Sopenharmony_ci def test_no_jump_to_non_integers(self): 25837db96d56Sopenharmony_ci self.run_test(no_jump_to_non_integers, 2, "Spam", [True]) 25847db96d56Sopenharmony_ci 25857db96d56Sopenharmony_ci def test_no_jump_without_trace_function(self): 25867db96d56Sopenharmony_ci # Must set sys.settrace(None) in setUp(), else condition is not 25877db96d56Sopenharmony_ci # triggered. 25887db96d56Sopenharmony_ci no_jump_without_trace_function() 25897db96d56Sopenharmony_ci 25907db96d56Sopenharmony_ci def test_large_function(self): 25917db96d56Sopenharmony_ci d = {} 25927db96d56Sopenharmony_ci exec("""def f(output): # line 0 25937db96d56Sopenharmony_ci x = 0 # line 1 25947db96d56Sopenharmony_ci y = 1 # line 2 25957db96d56Sopenharmony_ci ''' # line 3 25967db96d56Sopenharmony_ci %s # lines 4-1004 25977db96d56Sopenharmony_ci ''' # line 1005 25987db96d56Sopenharmony_ci x += 1 # line 1006 25997db96d56Sopenharmony_ci output.append(x) # line 1007 26007db96d56Sopenharmony_ci return""" % ('\n' * 1000,), d) 26017db96d56Sopenharmony_ci f = d['f'] 26027db96d56Sopenharmony_ci self.run_test(f, 2, 1007, [0]) 26037db96d56Sopenharmony_ci 26047db96d56Sopenharmony_ci def test_jump_to_firstlineno(self): 26057db96d56Sopenharmony_ci # This tests that PDB can jump back to the first line in a 26067db96d56Sopenharmony_ci # file. See issue #1689458. It can only be triggered in a 26077db96d56Sopenharmony_ci # function call if the function is defined on a single line. 26087db96d56Sopenharmony_ci code = compile(""" 26097db96d56Sopenharmony_ci# Comments don't count. 26107db96d56Sopenharmony_cioutput.append(2) # firstlineno is here. 26117db96d56Sopenharmony_cioutput.append(3) 26127db96d56Sopenharmony_cioutput.append(4) 26137db96d56Sopenharmony_ci""", "<fake module>", "exec") 26147db96d56Sopenharmony_ci class fake_function: 26157db96d56Sopenharmony_ci __code__ = code 26167db96d56Sopenharmony_ci tracer = JumpTracer(fake_function, 4, 1) 26177db96d56Sopenharmony_ci sys.settrace(tracer.trace) 26187db96d56Sopenharmony_ci namespace = {"output": []} 26197db96d56Sopenharmony_ci exec(code, namespace) 26207db96d56Sopenharmony_ci sys.settrace(None) 26217db96d56Sopenharmony_ci self.compare_jump_output([2, 3, 2, 3, 4], namespace["output"]) 26227db96d56Sopenharmony_ci 26237db96d56Sopenharmony_ci @jump_test(2, 3, [1], event='call', error=(ValueError, "can't jump from" 26247db96d56Sopenharmony_ci " the 'call' trace event of a new frame")) 26257db96d56Sopenharmony_ci def test_no_jump_from_call(output): 26267db96d56Sopenharmony_ci output.append(1) 26277db96d56Sopenharmony_ci def nested(): 26287db96d56Sopenharmony_ci output.append(3) 26297db96d56Sopenharmony_ci nested() 26307db96d56Sopenharmony_ci output.append(5) 26317db96d56Sopenharmony_ci 26327db96d56Sopenharmony_ci @jump_test(2, 1, [1], event='return', error=(ValueError, 26337db96d56Sopenharmony_ci "can only jump from a 'line' trace event")) 26347db96d56Sopenharmony_ci def test_no_jump_from_return_event(output): 26357db96d56Sopenharmony_ci output.append(1) 26367db96d56Sopenharmony_ci return 26377db96d56Sopenharmony_ci 26387db96d56Sopenharmony_ci @jump_test(2, 1, [1], event='exception', error=(ValueError, 26397db96d56Sopenharmony_ci "can only jump from a 'line' trace event")) 26407db96d56Sopenharmony_ci def test_no_jump_from_exception_event(output): 26417db96d56Sopenharmony_ci output.append(1) 26427db96d56Sopenharmony_ci 1 / 0 26437db96d56Sopenharmony_ci 26447db96d56Sopenharmony_ci @jump_test(3, 2, [2, 5], event='return') 26457db96d56Sopenharmony_ci def test_jump_from_yield(output): 26467db96d56Sopenharmony_ci def gen(): 26477db96d56Sopenharmony_ci output.append(2) 26487db96d56Sopenharmony_ci yield 3 26497db96d56Sopenharmony_ci next(gen()) 26507db96d56Sopenharmony_ci output.append(5) 26517db96d56Sopenharmony_ci 26527db96d56Sopenharmony_ci @jump_test(2, 3, [1, 3]) 26537db96d56Sopenharmony_ci def test_jump_forward_over_listcomp(output): 26547db96d56Sopenharmony_ci output.append(1) 26557db96d56Sopenharmony_ci x = [i for i in range(10)] 26567db96d56Sopenharmony_ci output.append(3) 26577db96d56Sopenharmony_ci 26587db96d56Sopenharmony_ci # checking for segfaults. 26597db96d56Sopenharmony_ci # See https://github.com/python/cpython/issues/92311 26607db96d56Sopenharmony_ci @jump_test(3, 1, []) 26617db96d56Sopenharmony_ci def test_jump_backward_over_listcomp(output): 26627db96d56Sopenharmony_ci a = 1 26637db96d56Sopenharmony_ci x = [i for i in range(10)] 26647db96d56Sopenharmony_ci c = 3 26657db96d56Sopenharmony_ci 26667db96d56Sopenharmony_ci @jump_test(8, 2, [2, 7, 2]) 26677db96d56Sopenharmony_ci def test_jump_backward_over_listcomp_v2(output): 26687db96d56Sopenharmony_ci flag = False 26697db96d56Sopenharmony_ci output.append(2) 26707db96d56Sopenharmony_ci if flag: 26717db96d56Sopenharmony_ci return 26727db96d56Sopenharmony_ci x = [i for i in range(5)] 26737db96d56Sopenharmony_ci flag = 6 26747db96d56Sopenharmony_ci output.append(7) 26757db96d56Sopenharmony_ci output.append(8) 26767db96d56Sopenharmony_ci 26777db96d56Sopenharmony_ci @async_jump_test(2, 3, [1, 3]) 26787db96d56Sopenharmony_ci async def test_jump_forward_over_async_listcomp(output): 26797db96d56Sopenharmony_ci output.append(1) 26807db96d56Sopenharmony_ci x = [i async for i in asynciter(range(10))] 26817db96d56Sopenharmony_ci output.append(3) 26827db96d56Sopenharmony_ci 26837db96d56Sopenharmony_ci @async_jump_test(3, 1, []) 26847db96d56Sopenharmony_ci async def test_jump_backward_over_async_listcomp(output): 26857db96d56Sopenharmony_ci a = 1 26867db96d56Sopenharmony_ci x = [i async for i in asynciter(range(10))] 26877db96d56Sopenharmony_ci c = 3 26887db96d56Sopenharmony_ci 26897db96d56Sopenharmony_ci @async_jump_test(8, 2, [2, 7, 2]) 26907db96d56Sopenharmony_ci async def test_jump_backward_over_async_listcomp_v2(output): 26917db96d56Sopenharmony_ci flag = False 26927db96d56Sopenharmony_ci output.append(2) 26937db96d56Sopenharmony_ci if flag: 26947db96d56Sopenharmony_ci return 26957db96d56Sopenharmony_ci x = [i async for i in asynciter(range(5))] 26967db96d56Sopenharmony_ci flag = 6 26977db96d56Sopenharmony_ci output.append(7) 26987db96d56Sopenharmony_ci output.append(8) 26997db96d56Sopenharmony_ci 27007db96d56Sopenharmony_ci # checking for segfaults. 27017db96d56Sopenharmony_ci @jump_test(3, 7, [], error=(ValueError, "stack")) 27027db96d56Sopenharmony_ci def test_jump_with_null_on_stack_load_global(output): 27037db96d56Sopenharmony_ci a = 1 27047db96d56Sopenharmony_ci print( 27057db96d56Sopenharmony_ci output.append(3) 27067db96d56Sopenharmony_ci ) 27077db96d56Sopenharmony_ci output.append(5) 27087db96d56Sopenharmony_ci ( 27097db96d56Sopenharmony_ci ( # 7 27107db96d56Sopenharmony_ci a 27117db96d56Sopenharmony_ci + 27127db96d56Sopenharmony_ci 10 27137db96d56Sopenharmony_ci ) 27147db96d56Sopenharmony_ci + 27157db96d56Sopenharmony_ci 13 27167db96d56Sopenharmony_ci ) 27177db96d56Sopenharmony_ci output.append(15) 27187db96d56Sopenharmony_ci 27197db96d56Sopenharmony_ci # checking for segfaults. 27207db96d56Sopenharmony_ci @jump_test(4, 8, [], error=(ValueError, "stack")) 27217db96d56Sopenharmony_ci def test_jump_with_null_on_stack_push_null(output): 27227db96d56Sopenharmony_ci a = 1 27237db96d56Sopenharmony_ci f = print 27247db96d56Sopenharmony_ci f( 27257db96d56Sopenharmony_ci output.append(4) 27267db96d56Sopenharmony_ci ) 27277db96d56Sopenharmony_ci output.append(6) 27287db96d56Sopenharmony_ci ( 27297db96d56Sopenharmony_ci ( # 8 27307db96d56Sopenharmony_ci a 27317db96d56Sopenharmony_ci + 27327db96d56Sopenharmony_ci 11 27337db96d56Sopenharmony_ci ) 27347db96d56Sopenharmony_ci + 27357db96d56Sopenharmony_ci 14 27367db96d56Sopenharmony_ci ) 27377db96d56Sopenharmony_ci output.append(16) 27387db96d56Sopenharmony_ci 27397db96d56Sopenharmony_ci # checking for segfaults. 27407db96d56Sopenharmony_ci @jump_test(3, 7, [], error=(ValueError, "stack")) 27417db96d56Sopenharmony_ci def test_jump_with_null_on_stack_load_attr(output): 27427db96d56Sopenharmony_ci a = 1 27437db96d56Sopenharmony_ci list.append( 27447db96d56Sopenharmony_ci output, 3 27457db96d56Sopenharmony_ci ) 27467db96d56Sopenharmony_ci output.append(5) 27477db96d56Sopenharmony_ci ( 27487db96d56Sopenharmony_ci ( # 7 27497db96d56Sopenharmony_ci a 27507db96d56Sopenharmony_ci + 27517db96d56Sopenharmony_ci 10 27527db96d56Sopenharmony_ci ) 27537db96d56Sopenharmony_ci + 27547db96d56Sopenharmony_ci 13 27557db96d56Sopenharmony_ci ) 27567db96d56Sopenharmony_ci output.append(15) 27577db96d56Sopenharmony_ci 27587db96d56Sopenharmony_ci @jump_test(2, 3, [1, 3]) 27597db96d56Sopenharmony_ci def test_jump_extended_args_unpack_ex_simple(output): 27607db96d56Sopenharmony_ci output.append(1) 27617db96d56Sopenharmony_ci _, *_, _ = output.append(2) or "Spam" 27627db96d56Sopenharmony_ci output.append(3) 27637db96d56Sopenharmony_ci 27647db96d56Sopenharmony_ci @jump_test(3, 4, [1, 4, 4, 5]) 27657db96d56Sopenharmony_ci def test_jump_extended_args_unpack_ex_tricky(output): 27667db96d56Sopenharmony_ci output.append(1) 27677db96d56Sopenharmony_ci ( 27687db96d56Sopenharmony_ci _, *_, _ 27697db96d56Sopenharmony_ci ) = output.append(4) or "Spam" 27707db96d56Sopenharmony_ci output.append(5) 27717db96d56Sopenharmony_ci 27727db96d56Sopenharmony_ci def test_jump_extended_args_for_iter(self): 27737db96d56Sopenharmony_ci # In addition to failing when extended arg handling is broken, this can 27747db96d56Sopenharmony_ci # also hang for a *very* long time: 27757db96d56Sopenharmony_ci source = [ 27767db96d56Sopenharmony_ci "def f(output):", 27777db96d56Sopenharmony_ci " output.append(1)", 27787db96d56Sopenharmony_ci " for _ in spam:", 27797db96d56Sopenharmony_ci *(f" output.append({i})" for i in range(3, 100_000)), 27807db96d56Sopenharmony_ci f" output.append(100_000)", 27817db96d56Sopenharmony_ci ] 27827db96d56Sopenharmony_ci namespace = {} 27837db96d56Sopenharmony_ci exec("\n".join(source), namespace) 27847db96d56Sopenharmony_ci f = namespace["f"] 27857db96d56Sopenharmony_ci self.run_test(f, 2, 100_000, [1, 100_000]) 27867db96d56Sopenharmony_ci 27877db96d56Sopenharmony_ci @jump_test(2, 3, [1, 3]) 27887db96d56Sopenharmony_ci def test_jump_or_pop(output): 27897db96d56Sopenharmony_ci output.append(1) 27907db96d56Sopenharmony_ci _ = output.append(2) and "Spam" 27917db96d56Sopenharmony_ci output.append(3) 27927db96d56Sopenharmony_ci 27937db96d56Sopenharmony_ci 27947db96d56Sopenharmony_ciclass TestExtendedArgs(unittest.TestCase): 27957db96d56Sopenharmony_ci 27967db96d56Sopenharmony_ci def setUp(self): 27977db96d56Sopenharmony_ci self.addCleanup(sys.settrace, sys.gettrace()) 27987db96d56Sopenharmony_ci sys.settrace(None) 27997db96d56Sopenharmony_ci 28007db96d56Sopenharmony_ci def count_traces(self, func): 28017db96d56Sopenharmony_ci # warmup 28027db96d56Sopenharmony_ci for _ in range(20): 28037db96d56Sopenharmony_ci func() 28047db96d56Sopenharmony_ci 28057db96d56Sopenharmony_ci counts = {"call": 0, "line": 0, "return": 0} 28067db96d56Sopenharmony_ci def trace(frame, event, arg): 28077db96d56Sopenharmony_ci counts[event] += 1 28087db96d56Sopenharmony_ci return trace 28097db96d56Sopenharmony_ci 28107db96d56Sopenharmony_ci sys.settrace(trace) 28117db96d56Sopenharmony_ci func() 28127db96d56Sopenharmony_ci sys.settrace(None) 28137db96d56Sopenharmony_ci 28147db96d56Sopenharmony_ci return counts 28157db96d56Sopenharmony_ci 28167db96d56Sopenharmony_ci def test_trace_unpack_long_sequence(self): 28177db96d56Sopenharmony_ci ns = {} 28187db96d56Sopenharmony_ci code = "def f():\n (" + "y,\n "*300 + ") = range(300)" 28197db96d56Sopenharmony_ci exec(code, ns) 28207db96d56Sopenharmony_ci counts = self.count_traces(ns["f"]) 28217db96d56Sopenharmony_ci self.assertEqual(counts, {'call': 1, 'line': 301, 'return': 1}) 28227db96d56Sopenharmony_ci 28237db96d56Sopenharmony_ci def test_trace_lots_of_globals(self): 28247db96d56Sopenharmony_ci code = """if 1: 28257db96d56Sopenharmony_ci def f(): 28267db96d56Sopenharmony_ci return ( 28277db96d56Sopenharmony_ci {} 28287db96d56Sopenharmony_ci ) 28297db96d56Sopenharmony_ci """.format("\n+\n".join(f"var{i}\n" for i in range(1000))) 28307db96d56Sopenharmony_ci ns = {f"var{i}": i for i in range(1000)} 28317db96d56Sopenharmony_ci exec(code, ns) 28327db96d56Sopenharmony_ci counts = self.count_traces(ns["f"]) 28337db96d56Sopenharmony_ci self.assertEqual(counts, {'call': 1, 'line': 2000, 'return': 1}) 28347db96d56Sopenharmony_ci 28357db96d56Sopenharmony_ci 28367db96d56Sopenharmony_ciclass TestEdgeCases(unittest.TestCase): 28377db96d56Sopenharmony_ci 28387db96d56Sopenharmony_ci def setUp(self): 28397db96d56Sopenharmony_ci self.addCleanup(sys.settrace, sys.gettrace()) 28407db96d56Sopenharmony_ci sys.settrace(None) 28417db96d56Sopenharmony_ci 28427db96d56Sopenharmony_ci def test_reentrancy(self): 28437db96d56Sopenharmony_ci def foo(*args): 28447db96d56Sopenharmony_ci ... 28457db96d56Sopenharmony_ci 28467db96d56Sopenharmony_ci def bar(*args): 28477db96d56Sopenharmony_ci ... 28487db96d56Sopenharmony_ci 28497db96d56Sopenharmony_ci class A: 28507db96d56Sopenharmony_ci def __call__(self, *args): 28517db96d56Sopenharmony_ci pass 28527db96d56Sopenharmony_ci 28537db96d56Sopenharmony_ci def __del__(self): 28547db96d56Sopenharmony_ci sys.settrace(bar) 28557db96d56Sopenharmony_ci 28567db96d56Sopenharmony_ci sys.settrace(A()) 28577db96d56Sopenharmony_ci with support.catch_unraisable_exception() as cm: 28587db96d56Sopenharmony_ci sys.settrace(foo) 28597db96d56Sopenharmony_ci self.assertEqual(cm.unraisable.object, A.__del__) 28607db96d56Sopenharmony_ci self.assertIsInstance(cm.unraisable.exc_value, RuntimeError) 28617db96d56Sopenharmony_ci 28627db96d56Sopenharmony_ci self.assertEqual(sys.gettrace(), foo) 28637db96d56Sopenharmony_ci 28647db96d56Sopenharmony_ci 28657db96d56Sopenharmony_ci def test_same_object(self): 28667db96d56Sopenharmony_ci def foo(*args): 28677db96d56Sopenharmony_ci ... 28687db96d56Sopenharmony_ci 28697db96d56Sopenharmony_ci sys.settrace(foo) 28707db96d56Sopenharmony_ci del foo 28717db96d56Sopenharmony_ci sys.settrace(sys.gettrace()) 28727db96d56Sopenharmony_ci 28737db96d56Sopenharmony_ci 28747db96d56Sopenharmony_ciif __name__ == "__main__": 28757db96d56Sopenharmony_ci unittest.main() 2876