• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Testing the line trace facility.
2
3from test import test_support
4import unittest
5import sys
6import difflib
7import gc
8from functools import wraps
9
10class tracecontext:
11    """Contex manager that traces its enter and exit."""
12    def __init__(self, output, value):
13        self.output = output
14        self.value = value
15
16    def __enter__(self):
17        self.output.append(self.value)
18
19    def __exit__(self, *exc_info):
20        self.output.append(-self.value)
21
22# A very basic example.  If this fails, we're in deep trouble.
23def basic():
24    return 1
25
26basic.events = [(0, 'call'),
27                (1, 'line'),
28                (1, 'return')]
29
30# Many of the tests below are tricky because they involve pass statements.
31# If there is implicit control flow around a pass statement (in an except
32# clause or else caluse) under what conditions do you set a line number
33# following that clause?
34
35
36# The entire "while 0:" statement is optimized away.  No code
37# exists for it, so the line numbers skip directly from "del x"
38# to "x = 1".
39def arigo_example():
40    x = 1
41    del x
42    while 0:
43        pass
44    x = 1
45
46arigo_example.events = [(0, 'call'),
47                        (1, 'line'),
48                        (2, 'line'),
49                        (5, 'line'),
50                        (5, 'return')]
51
52# check that lines consisting of just one instruction get traced:
53def one_instr_line():
54    x = 1
55    del x
56    x = 1
57
58one_instr_line.events = [(0, 'call'),
59                         (1, 'line'),
60                         (2, 'line'),
61                         (3, 'line'),
62                         (3, 'return')]
63
64def no_pop_tops():      # 0
65    x = 1               # 1
66    for a in range(2):  # 2
67        if a:           # 3
68            x = 1       # 4
69        else:           # 5
70            x = 1       # 6
71
72no_pop_tops.events = [(0, 'call'),
73                      (1, 'line'),
74                      (2, 'line'),
75                      (3, 'line'),
76                      (6, 'line'),
77                      (2, 'line'),
78                      (3, 'line'),
79                      (4, 'line'),
80                      (2, 'line'),
81                      (2, 'return')]
82
83def no_pop_blocks():
84    y = 1
85    while not y:
86        bla
87    x = 1
88
89no_pop_blocks.events = [(0, 'call'),
90                        (1, 'line'),
91                        (2, 'line'),
92                        (4, 'line'),
93                        (4, 'return')]
94
95def called(): # line -3
96    x = 1
97
98def call():   # line 0
99    called()
100
101call.events = [(0, 'call'),
102               (1, 'line'),
103               (-3, 'call'),
104               (-2, 'line'),
105               (-2, 'return'),
106               (1, 'return')]
107
108def raises():
109    raise Exception
110
111def test_raise():
112    try:
113        raises()
114    except Exception, exc:
115        x = 1
116
117test_raise.events = [(0, 'call'),
118                     (1, 'line'),
119                     (2, 'line'),
120                     (-3, 'call'),
121                     (-2, 'line'),
122                     (-2, 'exception'),
123                     (-2, 'return'),
124                     (2, 'exception'),
125                     (3, 'line'),
126                     (4, 'line'),
127                     (4, 'return')]
128
129def _settrace_and_return(tracefunc):
130    sys.settrace(tracefunc)
131    sys._getframe().f_back.f_trace = tracefunc
132def settrace_and_return(tracefunc):
133    _settrace_and_return(tracefunc)
134
135settrace_and_return.events = [(1, 'return')]
136
137def _settrace_and_raise(tracefunc):
138    sys.settrace(tracefunc)
139    sys._getframe().f_back.f_trace = tracefunc
140    raise RuntimeError
141def settrace_and_raise(tracefunc):
142    try:
143        _settrace_and_raise(tracefunc)
144    except RuntimeError, exc:
145        pass
146
147settrace_and_raise.events = [(2, 'exception'),
148                             (3, 'line'),
149                             (4, 'line'),
150                             (4, 'return')]
151
152# implicit return example
153# This test is interesting because of the else: pass
154# part of the code.  The code generate for the true
155# part of the if contains a jump past the else branch.
156# The compiler then generates an implicit "return None"
157# Internally, the compiler visits the pass statement
158# and stores its line number for use on the next instruction.
159# The next instruction is the implicit return None.
160def ireturn_example():
161    a = 5
162    b = 5
163    if a == b:
164        b = a+1
165    else:
166        pass
167
168ireturn_example.events = [(0, 'call'),
169                          (1, 'line'),
170                          (2, 'line'),
171                          (3, 'line'),
172                          (4, 'line'),
173                          (6, 'line'),
174                          (6, 'return')]
175
176# Tight loop with while(1) example (SF #765624)
177def tightloop_example():
178    items = range(0, 3)
179    try:
180        i = 0
181        while 1:
182            b = items[i]; i+=1
183    except IndexError:
184        pass
185
186tightloop_example.events = [(0, 'call'),
187                            (1, 'line'),
188                            (2, 'line'),
189                            (3, 'line'),
190                            (4, 'line'),
191                            (5, 'line'),
192                            (5, 'line'),
193                            (5, 'line'),
194                            (5, 'line'),
195                            (5, 'exception'),
196                            (6, 'line'),
197                            (7, 'line'),
198                            (7, 'return')]
199
200def tighterloop_example():
201    items = range(1, 4)
202    try:
203        i = 0
204        while 1: i = items[i]
205    except IndexError:
206        pass
207
208tighterloop_example.events = [(0, 'call'),
209                            (1, 'line'),
210                            (2, 'line'),
211                            (3, 'line'),
212                            (4, 'line'),
213                            (4, 'line'),
214                            (4, 'line'),
215                            (4, 'line'),
216                            (4, 'exception'),
217                            (5, 'line'),
218                            (6, 'line'),
219                            (6, 'return')]
220
221def generator_function():
222    try:
223        yield True
224        "continued"
225    finally:
226        "finally"
227def generator_example():
228    # any() will leave the generator before its end
229    x = any(generator_function())
230
231    # the following lines were not traced
232    for x in range(10):
233        y = x
234
235generator_example.events = ([(0, 'call'),
236                             (2, 'line'),
237                             (-6, 'call'),
238                             (-5, 'line'),
239                             (-4, 'line'),
240                             (-4, 'return'),
241                             (-4, 'call'),
242                             (-4, 'exception'),
243                             (-1, 'line'),
244                             (-1, 'return')] +
245                            [(5, 'line'), (6, 'line')] * 10 +
246                            [(5, 'line'), (5, 'return')])
247
248
249class Tracer:
250    def __init__(self):
251        self.events = []
252    def trace(self, frame, event, arg):
253        self.events.append((frame.f_lineno, event))
254        return self.trace
255    def traceWithGenexp(self, frame, event, arg):
256        (o for o in [1])
257        self.events.append((frame.f_lineno, event))
258        return self.trace
259
260class TraceTestCase(unittest.TestCase):
261
262    # Disable gc collection when tracing, otherwise the
263    # deallocators may be traced as well.
264    def setUp(self):
265        self.using_gc = gc.isenabled()
266        gc.disable()
267
268    def tearDown(self):
269        if self.using_gc:
270            gc.enable()
271
272    def compare_events(self, line_offset, events, expected_events):
273        events = [(l - line_offset, e) for (l, e) in events]
274        if events != expected_events:
275            self.fail(
276                "events did not match expectation:\n" +
277                "\n".join(difflib.ndiff([str(x) for x in expected_events],
278                                        [str(x) for x in events])))
279
280    def run_and_compare(self, func, events):
281        tracer = Tracer()
282        sys.settrace(tracer.trace)
283        func()
284        sys.settrace(None)
285        self.compare_events(func.func_code.co_firstlineno,
286                            tracer.events, events)
287
288    def run_test(self, func):
289        self.run_and_compare(func, func.events)
290
291    def run_test2(self, func):
292        tracer = Tracer()
293        func(tracer.trace)
294        sys.settrace(None)
295        self.compare_events(func.func_code.co_firstlineno,
296                            tracer.events, func.events)
297
298    def test_set_and_retrieve_none(self):
299        sys.settrace(None)
300        assert sys.gettrace() is None
301
302    def test_set_and_retrieve_func(self):
303        def fn(*args):
304            pass
305
306        sys.settrace(fn)
307        try:
308            assert sys.gettrace() is fn
309        finally:
310            sys.settrace(None)
311
312    def test_01_basic(self):
313        self.run_test(basic)
314    def test_02_arigo(self):
315        self.run_test(arigo_example)
316    def test_03_one_instr(self):
317        self.run_test(one_instr_line)
318    def test_04_no_pop_blocks(self):
319        self.run_test(no_pop_blocks)
320    def test_05_no_pop_tops(self):
321        self.run_test(no_pop_tops)
322    def test_06_call(self):
323        self.run_test(call)
324    def test_07_raise(self):
325        self.run_test(test_raise)
326
327    def test_08_settrace_and_return(self):
328        self.run_test2(settrace_and_return)
329    def test_09_settrace_and_raise(self):
330        self.run_test2(settrace_and_raise)
331    def test_10_ireturn(self):
332        self.run_test(ireturn_example)
333    def test_11_tightloop(self):
334        self.run_test(tightloop_example)
335    def test_12_tighterloop(self):
336        self.run_test(tighterloop_example)
337
338    def test_13_genexp(self):
339        self.run_test(generator_example)
340        # issue1265: if the trace function contains a generator,
341        # and if the traced function contains another generator
342        # that is not completely exhausted, the trace stopped.
343        # Worse: the 'finally' clause was not invoked.
344        tracer = Tracer()
345        sys.settrace(tracer.traceWithGenexp)
346        generator_example()
347        sys.settrace(None)
348        self.compare_events(generator_example.__code__.co_firstlineno,
349                            tracer.events, generator_example.events)
350
351    def test_14_onliner_if(self):
352        def onliners():
353            if True: False
354            else: True
355            return 0
356        self.run_and_compare(
357            onliners,
358            [(0, 'call'),
359             (1, 'line'),
360             (3, 'line'),
361             (3, 'return')])
362
363    def test_15_loops(self):
364        # issue1750076: "while" expression is skipped by debugger
365        def for_example():
366            for x in range(2):
367                pass
368        self.run_and_compare(
369            for_example,
370            [(0, 'call'),
371             (1, 'line'),
372             (2, 'line'),
373             (1, 'line'),
374             (2, 'line'),
375             (1, 'line'),
376             (1, 'return')])
377
378        def while_example():
379            # While expression should be traced on every loop
380            x = 2
381            while x > 0:
382                x -= 1
383        self.run_and_compare(
384            while_example,
385            [(0, 'call'),
386             (2, 'line'),
387             (3, 'line'),
388             (4, 'line'),
389             (3, 'line'),
390             (4, 'line'),
391             (3, 'line'),
392             (3, 'return')])
393
394    def test_16_blank_lines(self):
395        exec("def f():\n" + "\n" * 256 + "    pass")
396        self.run_and_compare(
397            f,
398            [(0, 'call'),
399             (257, 'line'),
400             (257, 'return')])
401
402    def test_17_none_f_trace(self):
403        # Issue 20041: fix TypeError when f_trace is set to None.
404        def func():
405            sys._getframe().f_trace = None
406            lineno = 2
407        self.run_and_compare(func,
408            [(0, 'call'),
409             (1, 'line')])
410
411
412class RaisingTraceFuncTestCase(unittest.TestCase):
413    def trace(self, frame, event, arg):
414        """A trace function that raises an exception in response to a
415        specific trace event."""
416        if event == self.raiseOnEvent:
417            raise ValueError # just something that isn't RuntimeError
418        else:
419            return self.trace
420
421    def f(self):
422        """The function to trace; raises an exception if that's the case
423        we're testing, so that the 'exception' trace event fires."""
424        if self.raiseOnEvent == 'exception':
425            x = 0
426            y = 1 // x
427        else:
428            return 1
429
430    def run_test_for_event(self, event):
431        """Tests that an exception raised in response to the given event is
432        handled OK."""
433        self.raiseOnEvent = event
434        try:
435            for i in xrange(sys.getrecursionlimit() + 1):
436                sys.settrace(self.trace)
437                try:
438                    self.f()
439                except ValueError:
440                    pass
441                else:
442                    self.fail("exception not raised!")
443        except RuntimeError:
444            self.fail("recursion counter not reset")
445
446    # Test the handling of exceptions raised by each kind of trace event.
447    def test_call(self):
448        self.run_test_for_event('call')
449    def test_line(self):
450        self.run_test_for_event('line')
451    def test_return(self):
452        self.run_test_for_event('return')
453    def test_exception(self):
454        self.run_test_for_event('exception')
455
456    def test_trash_stack(self):
457        def f():
458            for i in range(5):
459                print i  # line tracing will raise an exception at this line
460
461        def g(frame, why, extra):
462            if (why == 'line' and
463                frame.f_lineno == f.func_code.co_firstlineno + 2):
464                raise RuntimeError, "i am crashing"
465            return g
466
467        sys.settrace(g)
468        try:
469            f()
470        except RuntimeError:
471            # the test is really that this doesn't segfault:
472            import gc
473            gc.collect()
474        else:
475            self.fail("exception not propagated")
476
477
478# 'Jump' tests: assigning to frame.f_lineno within a trace function
479# moves the execution position - it's how debuggers implement a Jump
480# command (aka. "Set next statement").
481
482class JumpTracer:
483    """Defines a trace function that jumps from one place to another."""
484
485    def __init__(self, function, jumpFrom, jumpTo, event='line',
486                 decorated=False):
487        self.code = function.func_code
488        self.jumpFrom = jumpFrom
489        self.jumpTo = jumpTo
490        self.event = event
491        self.firstLine = None if decorated else self.code.co_firstlineno
492        self.done = False
493
494    def trace(self, frame, event, arg):
495        if self.done:
496            return
497        # frame.f_code.co_firstlineno is the first line of the decorator when
498        # 'function' is decorated and the decorator may be written using
499        # multiple physical lines when it is too long. Use the first line
500        # trace event in 'function' to find the first line of 'function'.
501        if (self.firstLine is None and frame.f_code == self.code and
502                event == 'line'):
503            self.firstLine = frame.f_lineno - 1
504        if (event == self.event and self.firstLine and
505                frame.f_lineno == self.firstLine + self.jumpFrom):
506            f = frame
507            while f is not None and f.f_code != self.code:
508                f = f.f_back
509            if f is not None:
510                # Cope with non-integer self.jumpTo (because of
511                # no_jump_to_non_integers below).
512                try:
513                    frame.f_lineno = self.firstLine + self.jumpTo
514                except TypeError:
515                    frame.f_lineno = self.jumpTo
516                self.done = True
517        return self.trace
518
519# This verifies the line-numbers-must-be-integers rule.
520def no_jump_to_non_integers(output):
521    try:
522        output.append(2)
523    except ValueError as e:
524        output.append('integer' in str(e))
525
526# This verifies that you can't set f_lineno via _getframe or similar
527# trickery.
528def no_jump_without_trace_function():
529    try:
530        previous_frame = sys._getframe().f_back
531        previous_frame.f_lineno = previous_frame.f_lineno
532    except ValueError as e:
533        # This is the exception we wanted; make sure the error message
534        # talks about trace functions.
535        if 'trace' not in str(e):
536            raise
537    else:
538        # Something's wrong - the expected exception wasn't raised.
539        raise AssertionError("Trace-function-less jump failed to fail")
540
541
542class JumpTestCase(unittest.TestCase):
543    def setUp(self):
544        self.addCleanup(sys.settrace, sys.gettrace())
545        sys.settrace(None)
546
547    def compare_jump_output(self, expected, received):
548        if received != expected:
549            self.fail( "Outputs don't match:\n" +
550                       "Expected: " + repr(expected) + "\n" +
551                       "Received: " + repr(received))
552
553    def run_test(self, func, jumpFrom, jumpTo, expected, error=None,
554                 event='line', decorated=False):
555        tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated)
556        sys.settrace(tracer.trace)
557        output = []
558        if error is None:
559            func(output)
560        else:
561            with self.assertRaisesRegexp(*error):
562                func(output)
563        sys.settrace(None)
564        self.compare_jump_output(expected, output)
565
566    def jump_test(jumpFrom, jumpTo, expected, error=None, event='line'):
567        """Decorator that creates a test that makes a jump
568        from one place to another in the following code.
569        """
570        def decorator(func):
571            @wraps(func)
572            def test(self):
573                self.run_test(func, jumpFrom, jumpTo, expected,
574                              error=error, event=event, decorated=True)
575            return test
576        return decorator
577
578    ## The first set of 'jump' tests are for things that are allowed:
579
580    @jump_test(1, 3, [3])
581    def test_jump_simple_forwards(output):
582        output.append(1)
583        output.append(2)
584        output.append(3)
585
586    @jump_test(2, 1, [1, 1, 2])
587    def test_jump_simple_backwards(output):
588        output.append(1)
589        output.append(2)
590
591    @jump_test(3, 5, [2, 5])
592    def test_jump_out_of_block_forwards(output):
593        for i in 1, 2:
594            output.append(2)
595            for j in [3]:  # Also tests jumping over a block
596                output.append(4)
597        output.append(5)
598
599    @jump_test(6, 1, [1, 3, 5, 1, 3, 5, 6, 7])
600    def test_jump_out_of_block_backwards(output):
601        output.append(1)
602        for i in [1]:
603            output.append(3)
604            for j in [2]:  # Also tests jumping over a block
605                output.append(5)
606            output.append(6)
607        output.append(7)
608
609    @jump_test(1, 2, [3])
610    def test_jump_to_codeless_line(output):
611        output.append(1)
612        # Jumping to this line should skip to the next one.
613        output.append(3)
614
615    @jump_test(2, 2, [1, 2, 3])
616    def test_jump_to_same_line(output):
617        output.append(1)
618        output.append(2)
619        output.append(3)
620
621    # Tests jumping within a finally block, and over one.
622    @jump_test(4, 9, [2, 9])
623    def test_jump_in_nested_finally(output):
624        try:
625            output.append(2)
626        finally:
627            output.append(4)
628            try:
629                output.append(6)
630            finally:
631                output.append(8)
632            output.append(9)
633
634    @jump_test(6, 7, [2, 7], (ZeroDivisionError, ''))
635    def test_jump_in_nested_finally_2(output):
636        try:
637            output.append(2)
638            1.0/0.0
639            return
640        finally:
641            output.append(6)
642            output.append(7)
643        output.append(8)
644
645    @jump_test(6, 11, [2, 11], (ZeroDivisionError, ''))
646    def test_jump_in_nested_finally_3(output):
647        try:
648            output.append(2)
649            1.0/0.0
650            return
651        finally:
652            output.append(6)
653            try:
654                output.append(8)
655            finally:
656                output.append(10)
657            output.append(11)
658        output.append(12)
659
660    @jump_test(3, 4, [1, 4])
661    def test_jump_infinite_while_loop(output):
662        output.append(1)
663        while True:
664            output.append(3)
665        output.append(4)
666
667    @jump_test(2, 3, [1, 3])
668    def test_jump_forwards_out_of_with_block(output):
669        with tracecontext(output, 1):
670            output.append(2)
671        output.append(3)
672
673    @jump_test(3, 1, [1, 2, 1, 2, 3, -2])
674    def test_jump_backwards_out_of_with_block(output):
675        output.append(1)
676        with tracecontext(output, 2):
677            output.append(3)
678
679    @jump_test(2, 5, [5])
680    def test_jump_forwards_out_of_try_finally_block(output):
681        try:
682            output.append(2)
683        finally:
684            output.append(4)
685        output.append(5)
686
687    @jump_test(3, 1, [1, 1, 3, 5])
688    def test_jump_backwards_out_of_try_finally_block(output):
689        output.append(1)
690        try:
691            output.append(3)
692        finally:
693            output.append(5)
694
695    @jump_test(2, 6, [6])
696    def test_jump_forwards_out_of_try_except_block(output):
697        try:
698            output.append(2)
699        except:
700            output.append(4)
701            raise
702        output.append(6)
703
704    @jump_test(3, 1, [1, 1, 3])
705    def test_jump_backwards_out_of_try_except_block(output):
706        output.append(1)
707        try:
708            output.append(3)
709        except:
710            output.append(5)
711            raise
712
713    @jump_test(5, 7, [4, 7, 8])
714    def test_jump_between_except_blocks(output):
715        try:
716            1.0/0.0
717        except ZeroDivisionError:
718            output.append(4)
719            output.append(5)
720        except FloatingPointError:
721            output.append(7)
722        output.append(8)
723
724    @jump_test(5, 6, [4, 6, 7])
725    def test_jump_within_except_block(output):
726        try:
727            1.0/0.0
728        except:
729            output.append(4)
730            output.append(5)
731            output.append(6)
732        output.append(7)
733
734    @jump_test(2, 4, [1, 4, 5, -4])
735    def test_jump_across_with(output):
736        output.append(1)
737        with tracecontext(output, 2):
738            output.append(3)
739        with tracecontext(output, 4):
740            output.append(5)
741
742    @jump_test(4, 5, [1, 3, 5, 6])
743    def test_jump_out_of_with_block_within_for_block(output):
744        output.append(1)
745        for i in [1]:
746            with tracecontext(output, 3):
747                output.append(4)
748            output.append(5)
749        output.append(6)
750
751    @jump_test(4, 5, [1, 2, 3, 5, -2, 6])
752    def test_jump_out_of_with_block_within_with_block(output):
753        output.append(1)
754        with tracecontext(output, 2):
755            with tracecontext(output, 3):
756                output.append(4)
757            output.append(5)
758        output.append(6)
759
760    @jump_test(5, 6, [2, 4, 6, 7])
761    def test_jump_out_of_with_block_within_finally_block(output):
762        try:
763            output.append(2)
764        finally:
765            with tracecontext(output, 4):
766                output.append(5)
767            output.append(6)
768        output.append(7)
769
770    @jump_test(8, 11, [1, 3, 5, 11, 12])
771    def test_jump_out_of_complex_nested_blocks(output):
772        output.append(1)
773        for i in [1]:
774            output.append(3)
775            for j in [1, 2]:
776                output.append(5)
777                try:
778                    for k in [1, 2]:
779                        output.append(8)
780                finally:
781                    output.append(10)
782            output.append(11)
783        output.append(12)
784
785    @jump_test(3, 5, [1, 2, 5])
786    def test_jump_out_of_with_assignment(output):
787        output.append(1)
788        with tracecontext(output, 2) \
789                as x:
790            output.append(4)
791        output.append(5)
792
793    @jump_test(3, 6, [1, 6, 8, 9])
794    def test_jump_over_return_in_try_finally_block(output):
795        output.append(1)
796        try:
797            output.append(3)
798            if not output: # always false
799                return
800            output.append(6)
801        finally:
802            output.append(8)
803        output.append(9)
804
805    @jump_test(5, 8, [1, 3, 8, 10, 11, 13])
806    def test_jump_over_break_in_try_finally_block(output):
807        output.append(1)
808        while True:
809            output.append(3)
810            try:
811                output.append(5)
812                if not output: # always false
813                    break
814                output.append(8)
815            finally:
816                output.append(10)
817            output.append(11)
818            break
819        output.append(13)
820
821    @jump_test(1, 7, [7, 8])
822    def test_jump_over_for_block_before_else(output):
823        output.append(1)
824        if not output:  # always false
825            for i in [3]:
826                output.append(4)
827        else:
828            output.append(6)
829            output.append(7)
830        output.append(8)
831
832    # The second set of 'jump' tests are for things that are not allowed:
833
834    @jump_test(2, 3, [1], (ValueError, 'after'))
835    def test_no_jump_too_far_forwards(output):
836        output.append(1)
837        output.append(2)
838
839    @jump_test(2, -2, [1], (ValueError, 'before'))
840    def test_no_jump_too_far_backwards(output):
841        output.append(1)
842        output.append(2)
843
844    # Test each kind of 'except' line.
845    @jump_test(2, 3, [4], (ValueError, 'except'))
846    def test_no_jump_to_except_1(output):
847        try:
848            output.append(2)
849        except:
850            output.append(4)
851            raise
852
853    @jump_test(2, 3, [4], (ValueError, 'except'))
854    def test_no_jump_to_except_2(output):
855        try:
856            output.append(2)
857        except ValueError:
858            output.append(4)
859            raise
860
861    @jump_test(2, 3, [4], (ValueError, 'except'))
862    def test_no_jump_to_except_3(output):
863        try:
864            output.append(2)
865        except ValueError as e:
866            output.append(4)
867            raise e
868
869    @jump_test(2, 3, [4], (ValueError, 'except'))
870    def test_no_jump_to_except_4(output):
871        try:
872            output.append(2)
873        except (ValueError, RuntimeError) as e:
874            output.append(4)
875            raise e
876
877    @jump_test(1, 3, [], (ValueError, 'into'))
878    def test_no_jump_forwards_into_for_block(output):
879        output.append(1)
880        for i in 1, 2:
881            output.append(3)
882
883    @jump_test(3, 2, [2, 2], (ValueError, 'into'))
884    def test_no_jump_backwards_into_for_block(output):
885        for i in 1, 2:
886            output.append(2)
887        output.append(3)
888
889    @jump_test(2, 4, [], (ValueError, 'into'))
890    def test_no_jump_forwards_into_while_block(output):
891        i = 1
892        output.append(2)
893        while i <= 2:
894            output.append(4)
895            i += 1
896
897    @jump_test(5, 3, [3, 3], (ValueError, 'into'))
898    def test_no_jump_backwards_into_while_block(output):
899        i = 1
900        while i <= 2:
901            output.append(3)
902            i += 1
903        output.append(5)
904
905    @jump_test(1, 3, [], (ValueError, 'into'))
906    def test_no_jump_forwards_into_with_block(output):
907        output.append(1)
908        with tracecontext(output, 2):
909            output.append(3)
910
911    @jump_test(3, 2, [1, 2, -1], (ValueError, 'into'))
912    def test_no_jump_backwards_into_with_block(output):
913        with tracecontext(output, 1):
914            output.append(2)
915        output.append(3)
916
917    @jump_test(1, 3, [], (ValueError, 'into'))
918    def test_no_jump_forwards_into_try_finally_block(output):
919        output.append(1)
920        try:
921            output.append(3)
922        finally:
923            output.append(5)
924
925    @jump_test(5, 2, [2, 4], (ValueError, 'into'))
926    def test_no_jump_backwards_into_try_finally_block(output):
927        try:
928            output.append(2)
929        finally:
930            output.append(4)
931        output.append(5)
932
933    @jump_test(1, 3, [], (ValueError, 'into'))
934    def test_no_jump_forwards_into_try_except_block(output):
935        output.append(1)
936        try:
937            output.append(3)
938        except:
939            output.append(5)
940            raise
941
942    @jump_test(6, 2, [2], (ValueError, 'into'))
943    def test_no_jump_backwards_into_try_except_block(output):
944        try:
945            output.append(2)
946        except:
947            output.append(4)
948            raise
949        output.append(6)
950
951    @jump_test(3, 6, [2, 5, 6], (ValueError, 'finally'))
952    def test_no_jump_into_finally_block(output):
953        try:
954            output.append(2)
955            output.append(3)
956        finally:  # still executed if the jump is failed
957            output.append(5)
958            output.append(6)
959        output.append(7)
960
961    @jump_test(1, 5, [], (ValueError, 'finally'))
962    def test_no_jump_into_finally_block_2(output):
963        output.append(1)
964        try:
965            output.append(3)
966        finally:
967            output.append(5)
968
969    @jump_test(5, 1, [1, 3], (ValueError, 'finally'))
970    def test_no_jump_out_of_finally_block(output):
971        output.append(1)
972        try:
973            output.append(3)
974        finally:
975            output.append(5)
976
977    @jump_test(3, 5, [1, 2, -2], (ValueError, 'into'))
978    def test_no_jump_between_with_blocks(output):
979        output.append(1)
980        with tracecontext(output, 2):
981            output.append(3)
982        with tracecontext(output, 4):
983            output.append(5)
984
985    @jump_test(7, 4, [1, 6], (ValueError, 'into'))
986    def test_no_jump_into_for_block_before_else(output):
987        output.append(1)
988        if not output:  # always false
989            for i in [3]:
990                output.append(4)
991        else:
992            output.append(6)
993            output.append(7)
994        output.append(8)
995
996    def test_no_jump_to_non_integers(self):
997        self.run_test(no_jump_to_non_integers, 2, "Spam", [True])
998
999    def test_no_jump_without_trace_function(self):
1000        # Must set sys.settrace(None) in setUp(), else condition is not
1001        # triggered.
1002        no_jump_without_trace_function()
1003
1004    def test_large_function(self):
1005        d = {}
1006        exec("""def f(output):        # line 0
1007            x = 0                     # line 1
1008            y = 1                     # line 2
1009            '''                       # line 3
1010            %s                        # lines 4-1004
1011            '''                       # line 1005
1012            x += 1                    # line 1006
1013            output.append(x)          # line 1007
1014            return""" % ('\n' * 1000,), d)
1015        f = d['f']
1016        self.run_test(f, 2, 1007, [0])
1017
1018    def test_jump_to_firstlineno(self):
1019        # This tests that PDB can jump back to the first line in a
1020        # file.  See issue #1689458.  It can only be triggered in a
1021        # function call if the function is defined on a single line.
1022        code = compile("""
1023# Comments don't count.
1024output.append(2)  # firstlineno is here.
1025output.append(3)
1026output.append(4)
1027""", "<fake module>", "exec")
1028        class fake_function:
1029            func_code = code
1030        tracer = JumpTracer(fake_function, 2, 0)
1031        sys.settrace(tracer.trace)
1032        namespace = {"output": []}
1033        exec code in namespace
1034        sys.settrace(None)
1035        self.compare_jump_output([2, 3, 2, 3, 4], namespace["output"])
1036
1037    @jump_test(2, 3, [1], event='call', error=(ValueError, "can't jump from"
1038               " the 'call' trace event of a new frame"))
1039    def test_no_jump_from_call(output):
1040        output.append(1)
1041        def nested():
1042            output.append(3)
1043        nested()
1044        output.append(5)
1045
1046    @jump_test(2, 1, [1], event='return', error=(ValueError,
1047               "can only jump from a 'line' trace event"))
1048    def test_no_jump_from_return_event(output):
1049        output.append(1)
1050        return
1051
1052    @jump_test(2, 1, [1], event='exception', error=(ValueError,
1053               "can only jump from a 'line' trace event"))
1054    def test_no_jump_from_exception_event(output):
1055        output.append(1)
1056        1 / 0
1057
1058    @jump_test(3, 2, [2], event='return', error=(ValueError,
1059               "can't jump from a yield statement"))
1060    def test_no_jump_from_yield(output):
1061        def gen():
1062            output.append(2)
1063            yield 3
1064        next(gen())
1065        output.append(5)
1066
1067
1068def test_main():
1069    test_support.run_unittest(
1070        TraceTestCase,
1071        RaisingTraceFuncTestCase,
1072        JumpTestCase
1073    )
1074
1075if __name__ == "__main__":
1076    test_main()
1077