~malept/ubuntu/lucid/python2.6/dev-dependency-fix

« back to all changes in this revision

Viewing changes to Lib/test/test_trace.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-02-13 12:51:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090213125100-uufgcb9yeqzujpqw
Tags: upstream-2.6.1
ImportĀ upstreamĀ versionĀ 2.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Testing the line trace facility.
 
2
 
 
3
from test import test_support
 
4
import unittest
 
5
import sys
 
6
import difflib
 
7
import gc
 
8
 
 
9
# A very basic example.  If this fails, we're in deep trouble.
 
10
def basic():
 
11
    return 1
 
12
 
 
13
basic.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".
 
26
def arigo_example():
 
27
    x = 1
 
28
    del x
 
29
    while 0:
 
30
        pass
 
31
    x = 1
 
32
 
 
33
arigo_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:
 
40
def one_instr_line():
 
41
    x = 1
 
42
    del x
 
43
    x = 1
 
44
 
 
45
one_instr_line.events = [(0, 'call'),
 
46
                         (1, 'line'),
 
47
                         (2, 'line'),
 
48
                         (3, 'line'),
 
49
                         (3, 'return')]
 
50
 
 
51
def 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
 
 
59
no_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
 
 
70
def no_pop_blocks():
 
71
    y = 1
 
72
    while not y:
 
73
        bla
 
74
    x = 1
 
75
 
 
76
no_pop_blocks.events = [(0, 'call'),
 
77
                        (1, 'line'),
 
78
                        (2, 'line'),
 
79
                        (4, 'line'),
 
80
                        (4, 'return')]
 
81
 
 
82
def called(): # line -3
 
83
    x = 1
 
84
 
 
85
def call():   # line 0
 
86
    called()
 
87
 
 
88
call.events = [(0, 'call'),
 
89
               (1, 'line'),
 
90
               (-3, 'call'),
 
91
               (-2, 'line'),
 
92
               (-2, 'return'),
 
93
               (1, 'return')]
 
94
 
 
95
def raises():
 
96
    raise Exception
 
97
 
 
98
def test_raise():
 
99
    try:
 
100
        raises()
 
101
    except Exception, exc:
 
102
        x = 1
 
103
 
 
104
test_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
 
 
116
def _settrace_and_return(tracefunc):
 
117
    sys.settrace(tracefunc)
 
118
    sys._getframe().f_back.f_trace = tracefunc
 
119
def settrace_and_return(tracefunc):
 
120
    _settrace_and_return(tracefunc)
 
121
 
 
122
settrace_and_return.events = [(1, 'return')]
 
123
 
 
124
def _settrace_and_raise(tracefunc):
 
125
    sys.settrace(tracefunc)
 
126
    sys._getframe().f_back.f_trace = tracefunc
 
127
    raise RuntimeError
 
128
def settrace_and_raise(tracefunc):
 
129
    try:
 
130
        _settrace_and_raise(tracefunc)
 
131
    except RuntimeError, exc:
 
132
        pass
 
133
 
 
134
settrace_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.
 
147
def ireturn_example():
 
148
    a = 5
 
149
    b = 5
 
150
    if a == b:
 
151
        b = a+1
 
152
    else:
 
153
        pass
 
154
 
 
155
ireturn_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)
 
164
def 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
 
 
173
tightloop_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
 
 
187
def tighterloop_example():
 
188
    items = range(1, 4)
 
189
    try:
 
190
        i = 0
 
191
        while 1: i = items[i]
 
192
    except IndexError:
 
193
        pass
 
194
 
 
195
tighterloop_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
 
 
208
def generator_function():
 
209
    try:
 
210
        yield True
 
211
        "continued"
 
212
    finally:
 
213
        "finally"
 
214
def 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
 
 
222
generator_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
 
 
236
class 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
 
 
247
class 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
 
 
255
    def tearDown(self):
 
256
        if self.using_gc:
 
257
            gc.enable()
 
258
 
 
259
    def compare_events(self, line_offset, events, expected_events):
 
260
        events = [(l - line_offset, e) for (l, e) in events]
 
261
        if events != expected_events:
 
262
            self.fail(
 
263
                "events did not match expectation:\n" +
 
264
                "\n".join(difflib.ndiff([str(x) for x in expected_events],
 
265
                                        [str(x) for x in events])))
 
266
 
 
267
    def run_and_compare(self, func, events):
 
268
        tracer = Tracer()
 
269
        sys.settrace(tracer.trace)
 
270
        func()
 
271
        sys.settrace(None)
 
272
        self.compare_events(func.func_code.co_firstlineno,
 
273
                            tracer.events, events)
 
274
 
 
275
    def run_test(self, func):
 
276
        self.run_and_compare(func, func.events)
 
277
 
 
278
    def run_test2(self, func):
 
279
        tracer = Tracer()
 
280
        func(tracer.trace)
 
281
        sys.settrace(None)
 
282
        self.compare_events(func.func_code.co_firstlineno,
 
283
                            tracer.events, func.events)
 
284
 
 
285
    def set_and_retrieve_none(self):
 
286
        sys.settrace(None)
 
287
        assert sys.gettrace() is None
 
288
 
 
289
    def set_and_retrieve_func(self):
 
290
        def fn(*args):
 
291
            pass
 
292
 
 
293
        sys.settrace(fn)
 
294
        try:
 
295
            assert sys.gettrace() is fn
 
296
        finally:
 
297
            sys.settrace(None)
 
298
 
 
299
    def test_01_basic(self):
 
300
        self.run_test(basic)
 
301
    def test_02_arigo(self):
 
302
        self.run_test(arigo_example)
 
303
    def test_03_one_instr(self):
 
304
        self.run_test(one_instr_line)
 
305
    def test_04_no_pop_blocks(self):
 
306
        self.run_test(no_pop_blocks)
 
307
    def test_05_no_pop_tops(self):
 
308
        self.run_test(no_pop_tops)
 
309
    def test_06_call(self):
 
310
        self.run_test(call)
 
311
    def test_07_raise(self):
 
312
        self.run_test(test_raise)
 
313
 
 
314
    def test_08_settrace_and_return(self):
 
315
        self.run_test2(settrace_and_return)
 
316
    def test_09_settrace_and_raise(self):
 
317
        self.run_test2(settrace_and_raise)
 
318
    def test_10_ireturn(self):
 
319
        self.run_test(ireturn_example)
 
320
    def test_11_tightloop(self):
 
321
        self.run_test(tightloop_example)
 
322
    def test_12_tighterloop(self):
 
323
        self.run_test(tighterloop_example)
 
324
 
 
325
    def test_13_genexp(self):
 
326
        self.run_test(generator_example)
 
327
        # issue1265: if the trace function contains a generator,
 
328
        # and if the traced function contains another generator
 
329
        # that is not completely exhausted, the trace stopped.
 
330
        # Worse: the 'finally' clause was not invoked.
 
331
        tracer = Tracer()
 
332
        sys.settrace(tracer.traceWithGenexp)
 
333
        generator_example()
 
334
        sys.settrace(None)
 
335
        self.compare_events(generator_example.__code__.co_firstlineno,
 
336
                            tracer.events, generator_example.events)
 
337
 
 
338
    def test_14_onliner_if(self):
 
339
        def onliners():
 
340
            if True: False
 
341
            else: True
 
342
            return 0
 
343
        self.run_and_compare(
 
344
            onliners,
 
345
            [(0, 'call'),
 
346
             (1, 'line'),
 
347
             (3, 'line'),
 
348
             (3, 'return')])
 
349
 
 
350
    def test_15_loops(self):
 
351
        # issue1750076: "while" expression is skipped by debugger
 
352
        def for_example():
 
353
            for x in range(2):
 
354
                pass
 
355
        self.run_and_compare(
 
356
            for_example,
 
357
            [(0, 'call'),
 
358
             (1, 'line'),
 
359
             (2, 'line'),
 
360
             (1, 'line'),
 
361
             (2, 'line'),
 
362
             (1, 'line'),
 
363
             (1, 'return')])
 
364
 
 
365
        def while_example():
 
366
            # While expression should be traced on every loop
 
367
            x = 2
 
368
            while x > 0:
 
369
                x -= 1
 
370
        self.run_and_compare(
 
371
            while_example,
 
372
            [(0, 'call'),
 
373
             (2, 'line'),
 
374
             (3, 'line'),
 
375
             (4, 'line'),
 
376
             (3, 'line'),
 
377
             (4, 'line'),
 
378
             (3, 'line'),
 
379
             (3, 'return')])
 
380
 
 
381
    def test_16_blank_lines(self):
 
382
        exec("def f():\n" + "\n" * 256 + "    pass")
 
383
        self.run_and_compare(
 
384
            f,
 
385
            [(0, 'call'),
 
386
             (257, 'line'),
 
387
             (257, 'return')])
 
388
 
 
389
 
 
390
class RaisingTraceFuncTestCase(unittest.TestCase):
 
391
    def trace(self, frame, event, arg):
 
392
        """A trace function that raises an exception in response to a
 
393
        specific trace event."""
 
394
        if event == self.raiseOnEvent:
 
395
            raise ValueError # just something that isn't RuntimeError
 
396
        else:
 
397
            return self.trace
 
398
 
 
399
    def f(self):
 
400
        """The function to trace; raises an exception if that's the case
 
401
        we're testing, so that the 'exception' trace event fires."""
 
402
        if self.raiseOnEvent == 'exception':
 
403
            x = 0
 
404
            y = 1/x
 
405
        else:
 
406
            return 1
 
407
 
 
408
    def run_test_for_event(self, event):
 
409
        """Tests that an exception raised in response to the given event is
 
410
        handled OK."""
 
411
        self.raiseOnEvent = event
 
412
        try:
 
413
            for i in xrange(sys.getrecursionlimit() + 1):
 
414
                sys.settrace(self.trace)
 
415
                try:
 
416
                    self.f()
 
417
                except ValueError:
 
418
                    pass
 
419
                else:
 
420
                    self.fail("exception not thrown!")
 
421
        except RuntimeError:
 
422
            self.fail("recursion counter not reset")
 
423
 
 
424
    # Test the handling of exceptions raised by each kind of trace event.
 
425
    def test_call(self):
 
426
        self.run_test_for_event('call')
 
427
    def test_line(self):
 
428
        self.run_test_for_event('line')
 
429
    def test_return(self):
 
430
        self.run_test_for_event('return')
 
431
    def test_exception(self):
 
432
        self.run_test_for_event('exception')
 
433
 
 
434
    def test_trash_stack(self):
 
435
        def f():
 
436
            for i in range(5):
 
437
                print i  # line tracing will raise an exception at this line
 
438
 
 
439
        def g(frame, why, extra):
 
440
            if (why == 'line' and
 
441
                frame.f_lineno == f.func_code.co_firstlineno + 2):
 
442
                raise RuntimeError, "i am crashing"
 
443
            return g
 
444
 
 
445
        sys.settrace(g)
 
446
        try:
 
447
            f()
 
448
        except RuntimeError:
 
449
            # the test is really that this doesn't segfault:
 
450
            import gc
 
451
            gc.collect()
 
452
        else:
 
453
            self.fail("exception not propagated")
 
454
 
 
455
 
 
456
# 'Jump' tests: assigning to frame.f_lineno within a trace function
 
457
# moves the execution position - it's how debuggers implement a Jump
 
458
# command (aka. "Set next statement").
 
459
 
 
460
class JumpTracer:
 
461
    """Defines a trace function that jumps from one place to another,
 
462
    with the source and destination lines of the jump being defined by
 
463
    the 'jump' property of the function under test."""
 
464
 
 
465
    def __init__(self, function):
 
466
        self.function = function
 
467
        self.jumpFrom = function.jump[0]
 
468
        self.jumpTo = function.jump[1]
 
469
        self.done = False
 
470
 
 
471
    def trace(self, frame, event, arg):
 
472
        if not self.done and frame.f_code == self.function.func_code:
 
473
            firstLine = frame.f_code.co_firstlineno
 
474
            if frame.f_lineno == firstLine + self.jumpFrom:
 
475
                # Cope with non-integer self.jumpTo (because of
 
476
                # no_jump_to_non_integers below).
 
477
                try:
 
478
                    frame.f_lineno = firstLine + self.jumpTo
 
479
                except TypeError:
 
480
                    frame.f_lineno = self.jumpTo
 
481
                self.done = True
 
482
        return self.trace
 
483
 
 
484
# The first set of 'jump' tests are for things that are allowed:
 
485
 
 
486
def jump_simple_forwards(output):
 
487
    output.append(1)
 
488
    output.append(2)
 
489
    output.append(3)
 
490
 
 
491
jump_simple_forwards.jump = (1, 3)
 
492
jump_simple_forwards.output = [3]
 
493
 
 
494
def jump_simple_backwards(output):
 
495
    output.append(1)
 
496
    output.append(2)
 
497
 
 
498
jump_simple_backwards.jump = (2, 1)
 
499
jump_simple_backwards.output = [1, 1, 2]
 
500
 
 
501
def jump_out_of_block_forwards(output):
 
502
    for i in 1, 2:
 
503
        output.append(2)
 
504
        for j in [3]:  # Also tests jumping over a block
 
505
            output.append(4)
 
506
    output.append(5)
 
507
 
 
508
jump_out_of_block_forwards.jump = (3, 5)
 
509
jump_out_of_block_forwards.output = [2, 5]
 
510
 
 
511
def jump_out_of_block_backwards(output):
 
512
    output.append(1)
 
513
    for i in [1]:
 
514
        output.append(3)
 
515
        for j in [2]:  # Also tests jumping over a block
 
516
            output.append(5)
 
517
        output.append(6)
 
518
    output.append(7)
 
519
 
 
520
jump_out_of_block_backwards.jump = (6, 1)
 
521
jump_out_of_block_backwards.output = [1, 3, 5, 1, 3, 5, 6, 7]
 
522
 
 
523
def jump_to_codeless_line(output):
 
524
    output.append(1)
 
525
    # Jumping to this line should skip to the next one.
 
526
    output.append(3)
 
527
 
 
528
jump_to_codeless_line.jump = (1, 2)
 
529
jump_to_codeless_line.output = [3]
 
530
 
 
531
def jump_to_same_line(output):
 
532
    output.append(1)
 
533
    output.append(2)
 
534
    output.append(3)
 
535
 
 
536
jump_to_same_line.jump = (2, 2)
 
537
jump_to_same_line.output = [1, 2, 3]
 
538
 
 
539
# Tests jumping within a finally block, and over one.
 
540
def jump_in_nested_finally(output):
 
541
    try:
 
542
        output.append(2)
 
543
    finally:
 
544
        output.append(4)
 
545
        try:
 
546
            output.append(6)
 
547
        finally:
 
548
            output.append(8)
 
549
        output.append(9)
 
550
 
 
551
jump_in_nested_finally.jump = (4, 9)
 
552
jump_in_nested_finally.output = [2, 9]
 
553
 
 
554
# The second set of 'jump' tests are for things that are not allowed:
 
555
 
 
556
def no_jump_too_far_forwards(output):
 
557
    try:
 
558
        output.append(2)
 
559
        output.append(3)
 
560
    except ValueError, e:
 
561
        output.append('after' in str(e))
 
562
 
 
563
no_jump_too_far_forwards.jump = (3, 6)
 
564
no_jump_too_far_forwards.output = [2, True]
 
565
 
 
566
def no_jump_too_far_backwards(output):
 
567
    try:
 
568
        output.append(2)
 
569
        output.append(3)
 
570
    except ValueError, e:
 
571
        output.append('before' in str(e))
 
572
 
 
573
no_jump_too_far_backwards.jump = (3, -1)
 
574
no_jump_too_far_backwards.output = [2, True]
 
575
 
 
576
# Test each kind of 'except' line.
 
577
def no_jump_to_except_1(output):
 
578
    try:
 
579
        output.append(2)
 
580
    except:
 
581
        e = sys.exc_info()[1]
 
582
        output.append('except' in str(e))
 
583
 
 
584
no_jump_to_except_1.jump = (2, 3)
 
585
no_jump_to_except_1.output = [True]
 
586
 
 
587
def no_jump_to_except_2(output):
 
588
    try:
 
589
        output.append(2)
 
590
    except ValueError:
 
591
        e = sys.exc_info()[1]
 
592
        output.append('except' in str(e))
 
593
 
 
594
no_jump_to_except_2.jump = (2, 3)
 
595
no_jump_to_except_2.output = [True]
 
596
 
 
597
def no_jump_to_except_3(output):
 
598
    try:
 
599
        output.append(2)
 
600
    except ValueError, e:
 
601
        output.append('except' in str(e))
 
602
 
 
603
no_jump_to_except_3.jump = (2, 3)
 
604
no_jump_to_except_3.output = [True]
 
605
 
 
606
def no_jump_to_except_4(output):
 
607
    try:
 
608
        output.append(2)
 
609
    except (ValueError, RuntimeError), e:
 
610
        output.append('except' in str(e))
 
611
 
 
612
no_jump_to_except_4.jump = (2, 3)
 
613
no_jump_to_except_4.output = [True]
 
614
 
 
615
def no_jump_forwards_into_block(output):
 
616
    try:
 
617
        output.append(2)
 
618
        for i in 1, 2:
 
619
            output.append(4)
 
620
    except ValueError, e:
 
621
        output.append('into' in str(e))
 
622
 
 
623
no_jump_forwards_into_block.jump = (2, 4)
 
624
no_jump_forwards_into_block.output = [True]
 
625
 
 
626
def no_jump_backwards_into_block(output):
 
627
    try:
 
628
        for i in 1, 2:
 
629
            output.append(3)
 
630
        output.append(4)
 
631
    except ValueError, e:
 
632
        output.append('into' in str(e))
 
633
 
 
634
no_jump_backwards_into_block.jump = (4, 3)
 
635
no_jump_backwards_into_block.output = [3, 3, True]
 
636
 
 
637
def no_jump_into_finally_block(output):
 
638
    try:
 
639
        try:
 
640
            output.append(3)
 
641
            x = 1
 
642
        finally:
 
643
            output.append(6)
 
644
    except ValueError, e:
 
645
        output.append('finally' in str(e))
 
646
 
 
647
no_jump_into_finally_block.jump = (4, 6)
 
648
no_jump_into_finally_block.output = [3, 6, True]  # The 'finally' still runs
 
649
 
 
650
def no_jump_out_of_finally_block(output):
 
651
    try:
 
652
        try:
 
653
            output.append(3)
 
654
        finally:
 
655
            output.append(5)
 
656
            output.append(6)
 
657
    except ValueError, e:
 
658
        output.append('finally' in str(e))
 
659
 
 
660
no_jump_out_of_finally_block.jump = (5, 1)
 
661
no_jump_out_of_finally_block.output = [3, True]
 
662
 
 
663
# This verifies the line-numbers-must-be-integers rule.
 
664
def no_jump_to_non_integers(output):
 
665
    try:
 
666
        output.append(2)
 
667
    except ValueError, e:
 
668
        output.append('integer' in str(e))
 
669
 
 
670
no_jump_to_non_integers.jump = (2, "Spam")
 
671
no_jump_to_non_integers.output = [True]
 
672
 
 
673
# This verifies that you can't set f_lineno via _getframe or similar
 
674
# trickery.
 
675
def no_jump_without_trace_function():
 
676
    try:
 
677
        previous_frame = sys._getframe().f_back
 
678
        previous_frame.f_lineno = previous_frame.f_lineno
 
679
    except ValueError, e:
 
680
        # This is the exception we wanted; make sure the error message
 
681
        # talks about trace functions.
 
682
        if 'trace' not in str(e):
 
683
            raise
 
684
    else:
 
685
        # Something's wrong - the expected exception wasn't raised.
 
686
        raise RuntimeError, "Trace-function-less jump failed to fail"
 
687
 
 
688
 
 
689
class JumpTestCase(unittest.TestCase):
 
690
    def compare_jump_output(self, expected, received):
 
691
        if received != expected:
 
692
            self.fail( "Outputs don't match:\n" +
 
693
                       "Expected: " + repr(expected) + "\n" +
 
694
                       "Received: " + repr(received))
 
695
 
 
696
    def run_test(self, func):
 
697
        tracer = JumpTracer(func)
 
698
        sys.settrace(tracer.trace)
 
699
        output = []
 
700
        func(output)
 
701
        sys.settrace(None)
 
702
        self.compare_jump_output(func.output, output)
 
703
 
 
704
    def test_01_jump_simple_forwards(self):
 
705
        self.run_test(jump_simple_forwards)
 
706
    def test_02_jump_simple_backwards(self):
 
707
        self.run_test(jump_simple_backwards)
 
708
    def test_03_jump_out_of_block_forwards(self):
 
709
        self.run_test(jump_out_of_block_forwards)
 
710
    def test_04_jump_out_of_block_backwards(self):
 
711
        self.run_test(jump_out_of_block_backwards)
 
712
    def test_05_jump_to_codeless_line(self):
 
713
        self.run_test(jump_to_codeless_line)
 
714
    def test_06_jump_to_same_line(self):
 
715
        self.run_test(jump_to_same_line)
 
716
    def test_07_jump_in_nested_finally(self):
 
717
        self.run_test(jump_in_nested_finally)
 
718
    def test_08_no_jump_too_far_forwards(self):
 
719
        self.run_test(no_jump_too_far_forwards)
 
720
    def test_09_no_jump_too_far_backwards(self):
 
721
        self.run_test(no_jump_too_far_backwards)
 
722
    def test_10_no_jump_to_except_1(self):
 
723
        self.run_test(no_jump_to_except_1)
 
724
    def test_11_no_jump_to_except_2(self):
 
725
        self.run_test(no_jump_to_except_2)
 
726
    def test_12_no_jump_to_except_3(self):
 
727
        self.run_test(no_jump_to_except_3)
 
728
    def test_13_no_jump_to_except_4(self):
 
729
        self.run_test(no_jump_to_except_4)
 
730
    def test_14_no_jump_forwards_into_block(self):
 
731
        self.run_test(no_jump_forwards_into_block)
 
732
    def test_15_no_jump_backwards_into_block(self):
 
733
        self.run_test(no_jump_backwards_into_block)
 
734
    def test_16_no_jump_into_finally_block(self):
 
735
        self.run_test(no_jump_into_finally_block)
 
736
    def test_17_no_jump_out_of_finally_block(self):
 
737
        self.run_test(no_jump_out_of_finally_block)
 
738
    def test_18_no_jump_to_non_integers(self):
 
739
        self.run_test(no_jump_to_non_integers)
 
740
    def test_19_no_jump_without_trace_function(self):
 
741
        no_jump_without_trace_function()
 
742
 
 
743
def test_main():
 
744
    test_support.run_unittest(
 
745
        TraceTestCase,
 
746
        RaisingTraceFuncTestCase,
 
747
        JumpTestCase
 
748
    )
 
749
 
 
750
if __name__ == "__main__":
 
751
    test_main()