• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Testing the line trace facility.
2
3from test import support
4import unittest
5import sys
6import difflib
7import gc
8
9# A very basic example.  If this fails, we're in deep trouble.
10def basic():
11    return 1
12
13basic.events = [(0, 'call'),
14                (1, 'line'),
15                (1, 'return')]
16
17# Many of the tests below are tricky because they involve pass statements.
18# If there is implicit control flow around a pass statement (in an except
19# clause or else caluse) under what conditions do you set a line number
20# following that clause?
21
22
23# The entire "while 0:" statement is optimized away.  No code
24# exists for it, so the line numbers skip directly from "del x"
25# to "x = 1".
26def arigo_example():
27    x = 1
28    del x
29    while 0:
30        pass
31    x = 1
32
33arigo_example.events = [(0, 'call'),
34                        (1, 'line'),
35                        (2, 'line'),
36                        (5, 'line'),
37                        (5, 'return')]
38
39# check that lines consisting of just one instruction get traced:
40def one_instr_line():
41    x = 1
42    del x
43    x = 1
44
45one_instr_line.events = [(0, 'call'),
46                         (1, 'line'),
47                         (2, 'line'),
48                         (3, 'line'),
49                         (3, 'return')]
50
51def no_pop_tops():      # 0
52    x = 1               # 1
53    for a in range(2):  # 2
54        if a:           # 3
55            x = 1       # 4
56        else:           # 5
57            x = 1       # 6
58
59no_pop_tops.events = [(0, 'call'),
60                      (1, 'line'),
61                      (2, 'line'),
62                      (3, 'line'),
63                      (6, 'line'),
64                      (2, 'line'),
65                      (3, 'line'),
66                      (4, 'line'),
67                      (2, 'line'),
68                      (2, 'return')]
69
70def no_pop_blocks():
71    y = 1
72    while not y:
73        bla
74    x = 1
75
76no_pop_blocks.events = [(0, 'call'),
77                        (1, 'line'),
78                        (2, 'line'),
79                        (4, 'line'),
80                        (4, 'return')]
81
82def called(): # line -3
83    x = 1
84
85def call():   # line 0
86    called()
87
88call.events = [(0, 'call'),
89               (1, 'line'),
90               (-3, 'call'),
91               (-2, 'line'),
92               (-2, 'return'),
93               (1, 'return')]
94
95def raises():
96    raise Exception
97
98def test_raise():
99    try:
100        raises()
101    except Exception as exc:
102        x = 1
103
104test_raise.events = [(0, 'call'),
105                     (1, 'line'),
106                     (2, 'line'),
107                     (-3, 'call'),
108                     (-2, 'line'),
109                     (-2, 'exception'),
110                     (-2, 'return'),
111                     (2, 'exception'),
112                     (3, 'line'),
113                     (4, 'line'),
114                     (4, 'return')]
115
116def _settrace_and_return(tracefunc):
117    sys.settrace(tracefunc)
118    sys._getframe().f_back.f_trace = tracefunc
119def settrace_and_return(tracefunc):
120    _settrace_and_return(tracefunc)
121
122settrace_and_return.events = [(1, 'return')]
123
124def _settrace_and_raise(tracefunc):
125    sys.settrace(tracefunc)
126    sys._getframe().f_back.f_trace = tracefunc
127    raise RuntimeError
128def settrace_and_raise(tracefunc):
129    try:
130        _settrace_and_raise(tracefunc)
131    except RuntimeError as exc:
132        pass
133
134settrace_and_raise.events = [(2, 'exception'),
135                             (3, 'line'),
136                             (4, 'line'),
137                             (4, 'return')]
138
139# implicit return example
140# This test is interesting because of the else: pass
141# part of the code.  The code generate for the true
142# part of the if contains a jump past the else branch.
143# The compiler then generates an implicit "return None"
144# Internally, the compiler visits the pass statement
145# and stores its line number for use on the next instruction.
146# The next instruction is the implicit return None.
147def ireturn_example():
148    a = 5
149    b = 5
150    if a == b:
151        b = a+1
152    else:
153        pass
154
155ireturn_example.events = [(0, 'call'),
156                          (1, 'line'),
157                          (2, 'line'),
158                          (3, 'line'),
159                          (4, 'line'),
160                          (6, 'line'),
161                          (6, 'return')]
162
163# Tight loop with while(1) example (SF #765624)
164def tightloop_example():
165    items = range(0, 3)
166    try:
167        i = 0
168        while 1:
169            b = items[i]; i+=1
170    except IndexError:
171        pass
172
173tightloop_example.events = [(0, 'call'),
174                            (1, 'line'),
175                            (2, 'line'),
176                            (3, 'line'),
177                            (4, 'line'),
178                            (5, 'line'),
179                            (5, 'line'),
180                            (5, 'line'),
181                            (5, 'line'),
182                            (5, 'exception'),
183                            (6, 'line'),
184                            (7, 'line'),
185                            (7, 'return')]
186
187def tighterloop_example():
188    items = range(1, 4)
189    try:
190        i = 0
191        while 1: i = items[i]
192    except IndexError:
193        pass
194
195tighterloop_example.events = [(0, 'call'),
196                            (1, 'line'),
197                            (2, 'line'),
198                            (3, 'line'),
199                            (4, 'line'),
200                            (4, 'line'),
201                            (4, 'line'),
202                            (4, 'line'),
203                            (4, 'exception'),
204                            (5, 'line'),
205                            (6, 'line'),
206                            (6, 'return')]
207
208def generator_function():
209    try:
210        yield True
211        "continued"
212    finally:
213        "finally"
214def generator_example():
215    # any() will leave the generator before its end
216    x = any(generator_function())
217
218    # the following lines were not traced
219    for x in range(10):
220        y = x
221
222generator_example.events = ([(0, 'call'),
223                             (2, 'line'),
224                             (-6, 'call'),
225                             (-5, 'line'),
226                             (-4, 'line'),
227                             (-4, 'return'),
228                             (-4, 'call'),
229                             (-4, 'exception'),
230                             (-1, 'line'),
231                             (-1, 'return')] +
232                            [(5, 'line'), (6, 'line')] * 10 +
233                            [(5, 'line'), (5, 'return')])
234
235
236class Tracer:
237    def __init__(self):
238        self.events = []
239    def trace(self, frame, event, arg):
240        self.events.append((frame.f_lineno, event))
241        return self.trace
242    def traceWithGenexp(self, frame, event, arg):
243        (o for o in [1])
244        self.events.append((frame.f_lineno, event))
245        return self.trace
246
247class TraceTestCase(unittest.TestCase):
248
249    # Disable gc collection when tracing, otherwise the
250    # deallocators may be traced as well.
251    def setUp(self):
252        self.using_gc = gc.isenabled()
253        gc.disable()
254        self.addCleanup(sys.settrace, sys.gettrace())
255
256    def tearDown(self):
257        if self.using_gc:
258            gc.enable()
259
260    def compare_events(self, line_offset, events, expected_events):
261        events = [(l - line_offset, e) for (l, e) in events]
262        if events != expected_events:
263            self.fail(
264                "events did not match expectation:\n" +
265                "\n".join(difflib.ndiff([str(x) for x in expected_events],
266                                        [str(x) for x in events])))
267
268    def run_and_compare(self, func, events):
269        tracer = Tracer()
270        sys.settrace(tracer.trace)
271        func()
272        sys.settrace(None)
273        self.compare_events(func.__code__.co_firstlineno,
274                            tracer.events, events)
275
276    def run_test(self, func):
277        self.run_and_compare(func, func.events)
278
279    def run_test2(self, func):
280        tracer = Tracer()
281        func(tracer.trace)
282        sys.settrace(None)
283        self.compare_events(func.__code__.co_firstlineno,
284                            tracer.events, func.events)
285
286    def test_set_and_retrieve_none(self):
287        sys.settrace(None)
288        assert sys.gettrace() is None
289
290    def test_set_and_retrieve_func(self):
291        def fn(*args):
292            pass
293
294        sys.settrace(fn)
295        try:
296            assert sys.gettrace() is fn
297        finally:
298            sys.settrace(None)
299
300    def test_01_basic(self):
301        self.run_test(basic)
302    def test_02_arigo(self):
303        self.run_test(arigo_example)
304    def test_03_one_instr(self):
305        self.run_test(one_instr_line)
306    def test_04_no_pop_blocks(self):
307        self.run_test(no_pop_blocks)
308    def test_05_no_pop_tops(self):
309        self.run_test(no_pop_tops)
310    def test_06_call(self):
311        self.run_test(call)
312    def test_07_raise(self):
313        self.run_test(test_raise)
314
315    def test_08_settrace_and_return(self):
316        self.run_test2(settrace_and_return)
317    def test_09_settrace_and_raise(self):
318        self.run_test2(settrace_and_raise)
319    def test_10_ireturn(self):
320        self.run_test(ireturn_example)
321    def test_11_tightloop(self):
322        self.run_test(tightloop_example)
323    def test_12_tighterloop(self):
324        self.run_test(tighterloop_example)
325
326    def test_13_genexp(self):
327        self.run_test(generator_example)
328        # issue1265: if the trace function contains a generator,
329        # and if the traced function contains another generator
330        # that is not completely exhausted, the trace stopped.
331        # Worse: the 'finally' clause was not invoked.
332        tracer = Tracer()
333        sys.settrace(tracer.traceWithGenexp)
334        generator_example()
335        sys.settrace(None)
336        self.compare_events(generator_example.__code__.co_firstlineno,
337                            tracer.events, generator_example.events)
338
339    def test_14_onliner_if(self):
340        def onliners():
341            if True: x=False
342            else: x=True
343            return 0
344        self.run_and_compare(
345            onliners,
346            [(0, 'call'),
347             (1, 'line'),
348             (3, 'line'),
349             (3, 'return')])
350
351    def test_15_loops(self):
352        # issue1750076: "while" expression is skipped by debugger
353        def for_example():
354            for x in range(2):
355                pass
356        self.run_and_compare(
357            for_example,
358            [(0, 'call'),
359             (1, 'line'),
360             (2, 'line'),
361             (1, 'line'),
362             (2, 'line'),
363             (1, 'line'),
364             (1, 'return')])
365
366        def while_example():
367            # While expression should be traced on every loop
368            x = 2
369            while x > 0:
370                x -= 1
371        self.run_and_compare(
372            while_example,
373            [(0, 'call'),
374             (2, 'line'),
375             (3, 'line'),
376             (4, 'line'),
377             (3, 'line'),
378             (4, 'line'),
379             (3, 'line'),
380             (3, 'return')])
381
382    def test_16_blank_lines(self):
383        namespace = {}
384        exec("def f():\n" + "\n" * 256 + "    pass", namespace)
385        self.run_and_compare(
386            namespace["f"],
387            [(0, 'call'),
388             (257, 'line'),
389             (257, 'return')])
390
391    def test_17_none_f_trace(self):
392        # Issue 20041: fix TypeError when f_trace is set to None.
393        def func():
394            sys._getframe().f_trace = None
395            lineno = 2
396        self.run_and_compare(func,
397            [(0, 'call'),
398             (1, 'line')])
399
400
401class RaisingTraceFuncTestCase(unittest.TestCase):
402    def setUp(self):
403        self.addCleanup(sys.settrace, sys.gettrace())
404
405    def trace(self, frame, event, arg):
406        """A trace function that raises an exception in response to a
407        specific trace event."""
408        if event == self.raiseOnEvent:
409            raise ValueError # just something that isn't RuntimeError
410        else:
411            return self.trace
412
413    def f(self):
414        """The function to trace; raises an exception if that's the case
415        we're testing, so that the 'exception' trace event fires."""
416        if self.raiseOnEvent == 'exception':
417            x = 0
418            y = 1/x
419        else:
420            return 1
421
422    def run_test_for_event(self, event):
423        """Tests that an exception raised in response to the given event is
424        handled OK."""
425        self.raiseOnEvent = event
426        try:
427            for i in range(sys.getrecursionlimit() + 1):
428                sys.settrace(self.trace)
429                try:
430                    self.f()
431                except ValueError:
432                    pass
433                else:
434                    self.fail("exception not raised!")
435        except RuntimeError:
436            self.fail("recursion counter not reset")
437
438    # Test the handling of exceptions raised by each kind of trace event.
439    def test_call(self):
440        self.run_test_for_event('call')
441    def test_line(self):
442        self.run_test_for_event('line')
443    def test_return(self):
444        self.run_test_for_event('return')
445    def test_exception(self):
446        self.run_test_for_event('exception')
447
448    def test_trash_stack(self):
449        def f():
450            for i in range(5):
451                print(i)  # line tracing will raise an exception at this line
452
453        def g(frame, why, extra):
454            if (why == 'line' and
455                frame.f_lineno == f.__code__.co_firstlineno + 2):
456                raise RuntimeError("i am crashing")
457            return g
458
459        sys.settrace(g)
460        try:
461            f()
462        except RuntimeError:
463            # the test is really that this doesn't segfault:
464            import gc
465            gc.collect()
466        else:
467            self.fail("exception not propagated")
468
469
470    def test_exception_arguments(self):
471        def f():
472            x = 0
473            # this should raise an error
474            x.no_such_attr
475        def g(frame, event, arg):
476            if (event == 'exception'):
477                type, exception, trace = arg
478                self.assertIsInstance(exception, Exception)
479            return g
480
481        existing = sys.gettrace()
482        try:
483            sys.settrace(g)
484            try:
485                f()
486            except AttributeError:
487                # this is expected
488                pass
489        finally:
490            sys.settrace(existing)
491
492
493# 'Jump' tests: assigning to frame.f_lineno within a trace function
494# moves the execution position - it's how debuggers implement a Jump
495# command (aka. "Set next statement").
496
497class JumpTracer:
498    """Defines a trace function that jumps from one place to another,
499    with the source and destination lines of the jump being defined by
500    the 'jump' property of the function under test."""
501
502    def __init__(self, function):
503        self.function = function
504        self.jumpFrom = function.jump[0]
505        self.jumpTo = function.jump[1]
506        self.done = False
507
508    def trace(self, frame, event, arg):
509        if not self.done and frame.f_code == self.function.__code__:
510            firstLine = frame.f_code.co_firstlineno
511            if event == 'line' and frame.f_lineno == firstLine + self.jumpFrom:
512                # Cope with non-integer self.jumpTo (because of
513                # no_jump_to_non_integers below).
514                try:
515                    frame.f_lineno = firstLine + self.jumpTo
516                except TypeError:
517                    frame.f_lineno = self.jumpTo
518                self.done = True
519        return self.trace
520
521# The first set of 'jump' tests are for things that are allowed:
522
523def jump_simple_forwards(output):
524    output.append(1)
525    output.append(2)
526    output.append(3)
527
528jump_simple_forwards.jump = (1, 3)
529jump_simple_forwards.output = [3]
530
531def jump_simple_backwards(output):
532    output.append(1)
533    output.append(2)
534
535jump_simple_backwards.jump = (2, 1)
536jump_simple_backwards.output = [1, 1, 2]
537
538def jump_out_of_block_forwards(output):
539    for i in 1, 2:
540        output.append(2)
541        for j in [3]:  # Also tests jumping over a block
542            output.append(4)
543    output.append(5)
544
545jump_out_of_block_forwards.jump = (3, 5)
546jump_out_of_block_forwards.output = [2, 5]
547
548def jump_out_of_block_backwards(output):
549    output.append(1)
550    for i in [1]:
551        output.append(3)
552        for j in [2]:  # Also tests jumping over a block
553            output.append(5)
554        output.append(6)
555    output.append(7)
556
557jump_out_of_block_backwards.jump = (6, 1)
558jump_out_of_block_backwards.output = [1, 3, 5, 1, 3, 5, 6, 7]
559
560def jump_to_codeless_line(output):
561    output.append(1)
562    # Jumping to this line should skip to the next one.
563    output.append(3)
564
565jump_to_codeless_line.jump = (1, 2)
566jump_to_codeless_line.output = [3]
567
568def jump_to_same_line(output):
569    output.append(1)
570    output.append(2)
571    output.append(3)
572
573jump_to_same_line.jump = (2, 2)
574jump_to_same_line.output = [1, 2, 3]
575
576# Tests jumping within a finally block, and over one.
577def jump_in_nested_finally(output):
578    try:
579        output.append(2)
580    finally:
581        output.append(4)
582        try:
583            output.append(6)
584        finally:
585            output.append(8)
586        output.append(9)
587
588jump_in_nested_finally.jump = (4, 9)
589jump_in_nested_finally.output = [2, 9]
590
591def jump_infinite_while_loop(output):
592    output.append(1)
593    while 1:
594        output.append(2)
595    output.append(3)
596
597jump_infinite_while_loop.jump = (3, 4)
598jump_infinite_while_loop.output = [1, 3]
599
600# The second set of 'jump' tests are for things that are not allowed:
601
602def no_jump_too_far_forwards(output):
603    try:
604        output.append(2)
605        output.append(3)
606    except ValueError as e:
607        output.append('after' in str(e))
608
609no_jump_too_far_forwards.jump = (3, 6)
610no_jump_too_far_forwards.output = [2, True]
611
612def no_jump_too_far_backwards(output):
613    try:
614        output.append(2)
615        output.append(3)
616    except ValueError as e:
617        output.append('before' in str(e))
618
619no_jump_too_far_backwards.jump = (3, -1)
620no_jump_too_far_backwards.output = [2, True]
621
622# Test each kind of 'except' line.
623def no_jump_to_except_1(output):
624    try:
625        output.append(2)
626    except:
627        e = sys.exc_info()[1]
628        output.append('except' in str(e))
629
630no_jump_to_except_1.jump = (2, 3)
631no_jump_to_except_1.output = [True]
632
633def no_jump_to_except_2(output):
634    try:
635        output.append(2)
636    except ValueError:
637        e = sys.exc_info()[1]
638        output.append('except' in str(e))
639
640no_jump_to_except_2.jump = (2, 3)
641no_jump_to_except_2.output = [True]
642
643def no_jump_to_except_3(output):
644    try:
645        output.append(2)
646    except ValueError as e:
647        output.append('except' in str(e))
648
649no_jump_to_except_3.jump = (2, 3)
650no_jump_to_except_3.output = [True]
651
652def no_jump_to_except_4(output):
653    try:
654        output.append(2)
655    except (ValueError, RuntimeError) as e:
656        output.append('except' in str(e))
657
658no_jump_to_except_4.jump = (2, 3)
659no_jump_to_except_4.output = [True]
660
661def no_jump_forwards_into_block(output):
662    try:
663        output.append(2)
664        for i in 1, 2:
665            output.append(4)
666    except ValueError as e:
667        output.append('into' in str(e))
668
669no_jump_forwards_into_block.jump = (2, 4)
670no_jump_forwards_into_block.output = [True]
671
672def no_jump_backwards_into_block(output):
673    try:
674        for i in 1, 2:
675            output.append(3)
676        output.append(4)
677    except ValueError as e:
678        output.append('into' in str(e))
679
680no_jump_backwards_into_block.jump = (4, 3)
681no_jump_backwards_into_block.output = [3, 3, True]
682
683def no_jump_into_finally_block(output):
684    try:
685        try:
686            output.append(3)
687            x = 1
688        finally:
689            output.append(6)
690    except ValueError as e:
691        output.append('finally' in str(e))
692
693no_jump_into_finally_block.jump = (4, 6)
694no_jump_into_finally_block.output = [3, 6, True]  # The 'finally' still runs
695
696def no_jump_out_of_finally_block(output):
697    try:
698        try:
699            output.append(3)
700        finally:
701            output.append(5)
702            output.append(6)
703    except ValueError as e:
704        output.append('finally' in str(e))
705
706no_jump_out_of_finally_block.jump = (5, 1)
707no_jump_out_of_finally_block.output = [3, True]
708
709# This verifies the line-numbers-must-be-integers rule.
710def no_jump_to_non_integers(output):
711    try:
712        output.append(2)
713    except ValueError as e:
714        output.append('integer' in str(e))
715
716no_jump_to_non_integers.jump = (2, "Spam")
717no_jump_to_non_integers.output = [True]
718
719def jump_across_with(output):
720    with open(support.TESTFN, "wb") as fp:
721        pass
722    with open(support.TESTFN, "wb") as fp:
723        pass
724jump_across_with.jump = (1, 3)
725jump_across_with.output = []
726
727# This verifies that you can't set f_lineno via _getframe or similar
728# trickery.
729def no_jump_without_trace_function():
730    try:
731        previous_frame = sys._getframe().f_back
732        previous_frame.f_lineno = previous_frame.f_lineno
733    except ValueError as e:
734        # This is the exception we wanted; make sure the error message
735        # talks about trace functions.
736        if 'trace' not in str(e):
737            raise
738    else:
739        # Something's wrong - the expected exception wasn't raised.
740        raise RuntimeError("Trace-function-less jump failed to fail")
741
742
743class JumpTestCase(unittest.TestCase):
744    def setUp(self):
745        self.addCleanup(sys.settrace, sys.gettrace())
746        sys.settrace(None)
747
748    def compare_jump_output(self, expected, received):
749        if received != expected:
750            self.fail( "Outputs don't match:\n" +
751                       "Expected: " + repr(expected) + "\n" +
752                       "Received: " + repr(received))
753
754    def run_test(self, func):
755        tracer = JumpTracer(func)
756        sys.settrace(tracer.trace)
757        output = []
758        func(output)
759        sys.settrace(None)
760        self.compare_jump_output(func.output, output)
761
762    def test_01_jump_simple_forwards(self):
763        self.run_test(jump_simple_forwards)
764    def test_02_jump_simple_backwards(self):
765        self.run_test(jump_simple_backwards)
766    def test_03_jump_out_of_block_forwards(self):
767        self.run_test(jump_out_of_block_forwards)
768    def test_04_jump_out_of_block_backwards(self):
769        self.run_test(jump_out_of_block_backwards)
770    def test_05_jump_to_codeless_line(self):
771        self.run_test(jump_to_codeless_line)
772    def test_06_jump_to_same_line(self):
773        self.run_test(jump_to_same_line)
774    def test_07_jump_in_nested_finally(self):
775        self.run_test(jump_in_nested_finally)
776    def test_jump_infinite_while_loop(self):
777        self.run_test(jump_infinite_while_loop)
778    def test_08_no_jump_too_far_forwards(self):
779        self.run_test(no_jump_too_far_forwards)
780    def test_09_no_jump_too_far_backwards(self):
781        self.run_test(no_jump_too_far_backwards)
782    def test_10_no_jump_to_except_1(self):
783        self.run_test(no_jump_to_except_1)
784    def test_11_no_jump_to_except_2(self):
785        self.run_test(no_jump_to_except_2)
786    def test_12_no_jump_to_except_3(self):
787        self.run_test(no_jump_to_except_3)
788    def test_13_no_jump_to_except_4(self):
789        self.run_test(no_jump_to_except_4)
790    def test_14_no_jump_forwards_into_block(self):
791        self.run_test(no_jump_forwards_into_block)
792    def test_15_no_jump_backwards_into_block(self):
793        self.run_test(no_jump_backwards_into_block)
794    def test_16_no_jump_into_finally_block(self):
795        self.run_test(no_jump_into_finally_block)
796    def test_17_no_jump_out_of_finally_block(self):
797        self.run_test(no_jump_out_of_finally_block)
798    def test_18_no_jump_to_non_integers(self):
799        self.run_test(no_jump_to_non_integers)
800    def test_19_no_jump_without_trace_function(self):
801        # Must set sys.settrace(None) in setUp(), else condition is not
802        # triggered.
803        no_jump_without_trace_function()
804    def test_jump_across_with(self):
805        self.addCleanup(support.unlink, support.TESTFN)
806        self.run_test(jump_across_with)
807
808    def test_20_large_function(self):
809        d = {}
810        exec("""def f(output):        # line 0
811            x = 0                     # line 1
812            y = 1                     # line 2
813            '''                       # line 3
814            %s                        # lines 4-1004
815            '''                       # line 1005
816            x += 1                    # line 1006
817            output.append(x)          # line 1007
818            return""" % ('\n' * 1000,), d)
819        f = d['f']
820
821        f.jump = (2, 1007)
822        f.output = [0]
823        self.run_test(f)
824
825    def test_jump_to_firstlineno(self):
826        # This tests that PDB can jump back to the first line in a
827        # file.  See issue #1689458.  It can only be triggered in a
828        # function call if the function is defined on a single line.
829        code = compile("""
830# Comments don't count.
831output.append(2)  # firstlineno is here.
832output.append(3)
833output.append(4)
834""", "<fake module>", "exec")
835        class fake_function:
836            __code__ = code
837            jump = (2, 0)
838        tracer = JumpTracer(fake_function)
839        sys.settrace(tracer.trace)
840        namespace = {"output": []}
841        exec(code, namespace)
842        sys.settrace(None)
843        self.compare_jump_output([2, 3, 2, 3, 4], namespace["output"])
844
845
846def test_main():
847    support.run_unittest(
848        TraceTestCase,
849        RaisingTraceFuncTestCase,
850        JumpTestCase
851    )
852
853if __name__ == "__main__":
854    test_main()
855