blob: 3ec00d29ab7b4711bf6f8b97e9d012113681bb1a [file] [log] [blame]
Michael W. Hudson53d58bb2002-08-30 13:09:51 +00001# Testing the line trace facility.
2
3from test import test_support
4import unittest
5import sys
6import difflib
7
8# A very basic example. If this fails, we're in deep trouble.
9def basic():
10 return 1
11
12basic.events = [(0, 'call'),
13 (1, 'line'),
14 (1, 'return')]
15
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000016# Many of the tests below are tricky because they involve pass statements.
17# If there is implicit control flow around a pass statement (in an except
18# clause or else caluse) under what conditions do you set a line number
19# following that clause?
20
21
22# The entire "while 0:" statement is optimized away. No code
23# exists for it, so the line numbers skip directly from "del x"
24# to "x = 1".
Michael W. Hudson53d58bb2002-08-30 13:09:51 +000025def arigo_example():
26 x = 1
27 del x
28 while 0:
29 pass
30 x = 1
31
32arigo_example.events = [(0, 'call'),
33 (1, 'line'),
34 (2, 'line'),
Michael W. Hudson53d58bb2002-08-30 13:09:51 +000035 (5, 'line'),
36 (5, 'return')]
37
38# check that lines consisting of just one instruction get traced:
39def one_instr_line():
40 x = 1
41 del x
42 x = 1
43
44one_instr_line.events = [(0, 'call'),
45 (1, 'line'),
46 (2, 'line'),
47 (3, 'line'),
48 (3, 'return')]
49
50def no_pop_tops(): # 0
51 x = 1 # 1
52 for a in range(2): # 2
53 if a: # 3
54 x = 1 # 4
55 else: # 5
56 x = 1 # 6
57
58no_pop_tops.events = [(0, 'call'),
59 (1, 'line'),
60 (2, 'line'),
61 (3, 'line'),
62 (6, 'line'),
63 (2, 'line'),
64 (3, 'line'),
65 (4, 'line'),
66 (2, 'line'),
Michael W. Hudson02ff6a92002-09-11 15:36:32 +000067 (2, 'return')]
Michael W. Hudson53d58bb2002-08-30 13:09:51 +000068
69def no_pop_blocks():
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000070 y = 1
71 while not y:
Michael W. Hudson53d58bb2002-08-30 13:09:51 +000072 bla
73 x = 1
74
75no_pop_blocks.events = [(0, 'call'),
76 (1, 'line'),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000077 (2, 'line'),
78 (4, 'line'),
79 (4, 'return')]
Michael W. Hudson53d58bb2002-08-30 13:09:51 +000080
Michael W. Hudson519a3422002-09-11 14:47:51 +000081def called(): # line -3
82 x = 1
83
84def call(): # line 0
85 called()
86
87call.events = [(0, 'call'),
88 (1, 'line'),
89 (-3, 'call'),
90 (-2, 'line'),
91 (-2, 'return'),
92 (1, 'return')]
93
94def raises():
95 raise Exception
96
97def test_raise():
98 try:
99 raises()
Guido van Rossumb940e112007-01-10 16:19:56 +0000100 except Exception as exc:
Michael W. Hudson519a3422002-09-11 14:47:51 +0000101 x = 1
102
103test_raise.events = [(0, 'call'),
104 (1, 'line'),
105 (2, 'line'),
106 (-3, 'call'),
107 (-2, 'line'),
108 (-2, 'exception'),
Barry Warsawe2eca0b2005-08-15 18:14:19 +0000109 (-2, 'return'),
Michael W. Hudson519a3422002-09-11 14:47:51 +0000110 (2, 'exception'),
111 (3, 'line'),
112 (4, 'line'),
113 (4, 'return')]
114
115def _settrace_and_return(tracefunc):
116 sys.settrace(tracefunc)
117 sys._getframe().f_back.f_trace = tracefunc
118def settrace_and_return(tracefunc):
119 _settrace_and_return(tracefunc)
Tim Peters3de75262002-11-09 05:26:15 +0000120
Michael W. Hudson519a3422002-09-11 14:47:51 +0000121settrace_and_return.events = [(1, 'return')]
122
123def _settrace_and_raise(tracefunc):
124 sys.settrace(tracefunc)
125 sys._getframe().f_back.f_trace = tracefunc
126 raise RuntimeError
127def settrace_and_raise(tracefunc):
128 try:
129 _settrace_and_raise(tracefunc)
Guido van Rossumb940e112007-01-10 16:19:56 +0000130 except RuntimeError as exc:
Michael W. Hudson519a3422002-09-11 14:47:51 +0000131 pass
Tim Peters3de75262002-11-09 05:26:15 +0000132
Michael W. Hudson519a3422002-09-11 14:47:51 +0000133settrace_and_raise.events = [(2, 'exception'),
134 (3, 'line'),
135 (4, 'line'),
136 (4, 'return')]
137
Nicholas Bastinaea94592004-03-22 18:30:42 +0000138# implicit return example
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000139# This test is interesting because of the else: pass
140# part of the code. The code generate for the true
141# part of the if contains a jump past the else branch.
142# The compiler then generates an implicit "return None"
143# Internally, the compiler visits the pass statement
144# and stores its line number for use on the next instruction.
145# The next instruction is the implicit return None.
Nicholas Bastinaea94592004-03-22 18:30:42 +0000146def ireturn_example():
147 a = 5
148 b = 5
149 if a == b:
150 b = a+1
151 else:
152 pass
153
154ireturn_example.events = [(0, 'call'),
155 (1, 'line'),
156 (2, 'line'),
157 (3, 'line'),
158 (4, 'line'),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000159 (6, 'line'),
160 (6, 'return')]
Nicholas Bastinaea94592004-03-22 18:30:42 +0000161
Nicholas Bastinfa7bec72004-03-22 19:21:47 +0000162# Tight loop with while(1) example (SF #765624)
163def tightloop_example():
164 items = range(0, 3)
165 try:
166 i = 0
167 while 1:
Nicholas Bastinee6c9b82004-03-22 19:23:46 +0000168 b = items[i]; i+=1
Nicholas Bastinfa7bec72004-03-22 19:21:47 +0000169 except IndexError:
170 pass
171
172tightloop_example.events = [(0, 'call'),
173 (1, 'line'),
174 (2, 'line'),
175 (3, 'line'),
176 (4, 'line'),
177 (5, 'line'),
178 (5, 'line'),
179 (5, 'line'),
Nicholas Bastinee6c9b82004-03-22 19:23:46 +0000180 (5, 'line'),
Nicholas Bastinfa7bec72004-03-22 19:21:47 +0000181 (5, 'exception'),
182 (6, 'line'),
183 (7, 'line'),
184 (7, 'return')]
185
Armin Rigo70693382004-03-22 19:30:39 +0000186def tighterloop_example():
187 items = range(1, 4)
188 try:
189 i = 0
190 while 1: i = items[i]
191 except IndexError:
192 pass
193
194tighterloop_example.events = [(0, 'call'),
195 (1, 'line'),
196 (2, 'line'),
197 (3, 'line'),
198 (4, 'line'),
199 (4, 'line'),
200 (4, 'line'),
201 (4, 'line'),
202 (4, 'exception'),
203 (5, 'line'),
204 (6, 'line'),
205 (6, 'return')]
206
Amaury Forgeot d'Arcf05149a2007-11-13 01:05:30 +0000207def generator_function():
208 try:
209 yield True
210 "continued"
211 finally:
212 "finally"
213def generator_example():
214 # any() will leave the generator before its end
215 x = any(generator_function())
216
217 # the following lines were not traced
218 for x in range(10):
219 y = x
220
221generator_example.events = ([(0, 'call'),
222 (2, 'line'),
223 (-6, 'call'),
224 (-5, 'line'),
225 (-4, 'line'),
226 (-4, 'return'),
227 (-4, 'call'),
228 (-4, 'exception'),
229 (-1, 'line'),
230 (-1, 'return')] +
231 [(5, 'line'), (6, 'line')] * 10 +
232 [(5, 'line'), (5, 'return')])
233
234
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000235class Tracer:
236 def __init__(self):
237 self.events = []
238 def trace(self, frame, event, arg):
239 self.events.append((frame.f_lineno, event))
240 return self.trace
Amaury Forgeot d'Arcf05149a2007-11-13 01:05:30 +0000241 def traceWithGenexp(self, frame, event, arg):
242 (o for o in [1])
243 self.events.append((frame.f_lineno, event))
244 return self.trace
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000245
246class TraceTestCase(unittest.TestCase):
Michael W. Hudson519a3422002-09-11 14:47:51 +0000247 def compare_events(self, line_offset, events, expected_events):
Tim Peters3de75262002-11-09 05:26:15 +0000248 events = [(l - line_offset, e) for (l, e) in events]
Michael W. Hudson519a3422002-09-11 14:47:51 +0000249 if events != expected_events:
250 self.fail(
251 "events did not match expectation:\n" +
Amaury Forgeot d'Arcf05149a2007-11-13 01:05:30 +0000252 "\n".join(difflib.ndiff([str(x) for x in expected_events],
253 [str(x) for x in events])))
Tim Peters3de75262002-11-09 05:26:15 +0000254
255
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000256 def run_test(self, func):
257 tracer = Tracer()
258 sys.settrace(tracer.trace)
259 func()
260 sys.settrace(None)
Neal Norwitz221085d2007-02-25 20:55:47 +0000261 self.compare_events(func.__code__.co_firstlineno,
Michael W. Hudson519a3422002-09-11 14:47:51 +0000262 tracer.events, func.events)
263
264 def run_test2(self, func):
265 tracer = Tracer()
266 func(tracer.trace)
267 sys.settrace(None)
Neal Norwitz221085d2007-02-25 20:55:47 +0000268 self.compare_events(func.__code__.co_firstlineno,
Michael W. Hudson519a3422002-09-11 14:47:51 +0000269 tracer.events, func.events)
Tim Peters3de75262002-11-09 05:26:15 +0000270
Nicholas Bastinaea94592004-03-22 18:30:42 +0000271 def test_01_basic(self):
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000272 self.run_test(basic)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000273 def test_02_arigo(self):
274 self.run_test(arigo_example)
Nicholas Bastinaea94592004-03-22 18:30:42 +0000275 def test_03_one_instr(self):
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000276 self.run_test(one_instr_line)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000277 def test_04_no_pop_blocks(self):
278 self.run_test(no_pop_blocks)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000279 def test_05_no_pop_tops(self):
280 self.run_test(no_pop_tops)
Nicholas Bastinaea94592004-03-22 18:30:42 +0000281 def test_06_call(self):
Michael W. Hudson519a3422002-09-11 14:47:51 +0000282 self.run_test(call)
Nicholas Bastinaea94592004-03-22 18:30:42 +0000283 def test_07_raise(self):
Michael W. Hudson519a3422002-09-11 14:47:51 +0000284 self.run_test(test_raise)
285
Nicholas Bastinaea94592004-03-22 18:30:42 +0000286 def test_08_settrace_and_return(self):
Michael W. Hudson519a3422002-09-11 14:47:51 +0000287 self.run_test2(settrace_and_return)
Nicholas Bastinaea94592004-03-22 18:30:42 +0000288 def test_09_settrace_and_raise(self):
Michael W. Hudson519a3422002-09-11 14:47:51 +0000289 self.run_test2(settrace_and_raise)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000290 def test_10_ireturn(self):
291 self.run_test(ireturn_example)
Nicholas Bastinfa7bec72004-03-22 19:21:47 +0000292 def test_11_tightloop(self):
293 self.run_test(tightloop_example)
Armin Rigo70693382004-03-22 19:30:39 +0000294 def test_12_tighterloop(self):
295 self.run_test(tighterloop_example)
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000296
Amaury Forgeot d'Arcf05149a2007-11-13 01:05:30 +0000297 def test_13_genexp(self):
298 self.run_test(generator_example)
299 # issue1265: if the trace function contains a generator,
300 # and if the traced function contains another generator
301 # that is not completely exhausted, the trace stopped.
302 # Worse: the 'finally' clause was not invoked.
303 tracer = Tracer()
304 sys.settrace(tracer.traceWithGenexp)
305 generator_example()
306 sys.settrace(None)
307 self.compare_events(generator_example.__code__.co_firstlineno,
308 tracer.events, generator_example.events)
309
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000310class RaisingTraceFuncTestCase(unittest.TestCase):
Michael W. Hudson006c7522002-11-08 13:08:46 +0000311 def trace(self, frame, event, arg):
312 """A trace function that raises an exception in response to a
313 specific trace event."""
314 if event == self.raiseOnEvent:
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000315 raise ValueError # just something that isn't RuntimeError
Michael W. Hudson006c7522002-11-08 13:08:46 +0000316 else:
317 return self.trace
Tim Peters3de75262002-11-09 05:26:15 +0000318
Michael W. Hudson006c7522002-11-08 13:08:46 +0000319 def f(self):
320 """The function to trace; raises an exception if that's the case
321 we're testing, so that the 'exception' trace event fires."""
322 if self.raiseOnEvent == 'exception':
323 x = 0
324 y = 1/x
325 else:
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000326 return 1
Tim Peters3de75262002-11-09 05:26:15 +0000327
Michael W. Hudson006c7522002-11-08 13:08:46 +0000328 def run_test_for_event(self, event):
329 """Tests that an exception raised in response to the given event is
330 handled OK."""
331 self.raiseOnEvent = event
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000332 try:
Guido van Rossum805365e2007-05-07 22:24:25 +0000333 for i in range(sys.getrecursionlimit() + 1):
Michael W. Hudson006c7522002-11-08 13:08:46 +0000334 sys.settrace(self.trace)
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000335 try:
Michael W. Hudson006c7522002-11-08 13:08:46 +0000336 self.f()
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000337 except ValueError:
338 pass
339 else:
340 self.fail("exception not thrown!")
341 except RuntimeError:
342 self.fail("recursion counter not reset")
Tim Peters3de75262002-11-09 05:26:15 +0000343
Michael W. Hudson006c7522002-11-08 13:08:46 +0000344 # Test the handling of exceptions raised by each kind of trace event.
345 def test_call(self):
346 self.run_test_for_event('call')
347 def test_line(self):
348 self.run_test_for_event('line')
349 def test_return(self):
350 self.run_test_for_event('return')
351 def test_exception(self):
352 self.run_test_for_event('exception')
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000353
Michael W. Hudson58ee2af2003-04-29 16:18:47 +0000354 def test_trash_stack(self):
355 def f():
356 for i in range(5):
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000357 print(i) # line tracing will raise an exception at this line
Michael W. Hudson58ee2af2003-04-29 16:18:47 +0000358
359 def g(frame, why, extra):
360 if (why == 'line' and
Neal Norwitz221085d2007-02-25 20:55:47 +0000361 frame.f_lineno == f.__code__.co_firstlineno + 2):
Collin Winter3add4d72007-08-29 23:37:32 +0000362 raise RuntimeError("i am crashing")
Michael W. Hudson58ee2af2003-04-29 16:18:47 +0000363 return g
364
365 sys.settrace(g)
366 try:
367 f()
368 except RuntimeError:
369 # the test is really that this doesn't segfault:
370 import gc
371 gc.collect()
372 else:
373 self.fail("exception not propagated")
374
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000375
376# 'Jump' tests: assigning to frame.f_lineno within a trace function
377# moves the execution position - it's how debuggers implement a Jump
378# command (aka. "Set next statement").
379
380class JumpTracer:
381 """Defines a trace function that jumps from one place to another,
382 with the source and destination lines of the jump being defined by
383 the 'jump' property of the function under test."""
384
385 def __init__(self, function):
386 self.function = function
387 self.jumpFrom = function.jump[0]
388 self.jumpTo = function.jump[1]
389 self.done = False
390
391 def trace(self, frame, event, arg):
Neal Norwitz221085d2007-02-25 20:55:47 +0000392 if not self.done and frame.f_code == self.function.__code__:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000393 firstLine = frame.f_code.co_firstlineno
394 if frame.f_lineno == firstLine + self.jumpFrom:
395 # Cope with non-integer self.jumpTo (because of
396 # no_jump_to_non_integers below).
397 try:
398 frame.f_lineno = firstLine + self.jumpTo
399 except TypeError:
400 frame.f_lineno = self.jumpTo
401 self.done = True
402 return self.trace
403
404# The first set of 'jump' tests are for things that are allowed:
405
406def jump_simple_forwards(output):
407 output.append(1)
408 output.append(2)
409 output.append(3)
410
411jump_simple_forwards.jump = (1, 3)
412jump_simple_forwards.output = [3]
413
414def jump_simple_backwards(output):
415 output.append(1)
416 output.append(2)
417
418jump_simple_backwards.jump = (2, 1)
419jump_simple_backwards.output = [1, 1, 2]
420
421def jump_out_of_block_forwards(output):
422 for i in 1, 2:
423 output.append(2)
424 for j in [3]: # Also tests jumping over a block
425 output.append(4)
426 output.append(5)
427
428jump_out_of_block_forwards.jump = (3, 5)
429jump_out_of_block_forwards.output = [2, 5]
430
431def jump_out_of_block_backwards(output):
432 output.append(1)
433 for i in [1]:
434 output.append(3)
435 for j in [2]: # Also tests jumping over a block
436 output.append(5)
437 output.append(6)
438 output.append(7)
439
440jump_out_of_block_backwards.jump = (6, 1)
441jump_out_of_block_backwards.output = [1, 3, 5, 1, 3, 5, 6, 7]
442
443def jump_to_codeless_line(output):
444 output.append(1)
445 # Jumping to this line should skip to the next one.
446 output.append(3)
447
448jump_to_codeless_line.jump = (1, 2)
449jump_to_codeless_line.output = [3]
450
451def jump_to_same_line(output):
452 output.append(1)
453 output.append(2)
454 output.append(3)
455
456jump_to_same_line.jump = (2, 2)
457jump_to_same_line.output = [1, 2, 3]
458
459# Tests jumping within a finally block, and over one.
460def jump_in_nested_finally(output):
461 try:
462 output.append(2)
463 finally:
464 output.append(4)
465 try:
466 output.append(6)
467 finally:
468 output.append(8)
469 output.append(9)
470
471jump_in_nested_finally.jump = (4, 9)
472jump_in_nested_finally.output = [2, 9]
473
474# The second set of 'jump' tests are for things that are not allowed:
475
476def no_jump_too_far_forwards(output):
477 try:
478 output.append(2)
479 output.append(3)
Guido van Rossumb940e112007-01-10 16:19:56 +0000480 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000481 output.append('after' in str(e))
482
483no_jump_too_far_forwards.jump = (3, 6)
484no_jump_too_far_forwards.output = [2, True]
485
486def no_jump_too_far_backwards(output):
487 try:
488 output.append(2)
489 output.append(3)
Guido van Rossumb940e112007-01-10 16:19:56 +0000490 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000491 output.append('before' in str(e))
492
493no_jump_too_far_backwards.jump = (3, -1)
494no_jump_too_far_backwards.output = [2, True]
495
496# Test each kind of 'except' line.
497def no_jump_to_except_1(output):
498 try:
499 output.append(2)
500 except:
501 e = sys.exc_info()[1]
502 output.append('except' in str(e))
503
504no_jump_to_except_1.jump = (2, 3)
505no_jump_to_except_1.output = [True]
506
507def no_jump_to_except_2(output):
508 try:
509 output.append(2)
510 except ValueError:
511 e = sys.exc_info()[1]
512 output.append('except' in str(e))
513
514no_jump_to_except_2.jump = (2, 3)
515no_jump_to_except_2.output = [True]
516
517def no_jump_to_except_3(output):
518 try:
519 output.append(2)
Guido van Rossumb940e112007-01-10 16:19:56 +0000520 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000521 output.append('except' in str(e))
522
523no_jump_to_except_3.jump = (2, 3)
524no_jump_to_except_3.output = [True]
525
526def no_jump_to_except_4(output):
527 try:
528 output.append(2)
Guido van Rossumb940e112007-01-10 16:19:56 +0000529 except (ValueError, RuntimeError) as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000530 output.append('except' in str(e))
531
532no_jump_to_except_4.jump = (2, 3)
533no_jump_to_except_4.output = [True]
534
535def no_jump_forwards_into_block(output):
536 try:
537 output.append(2)
538 for i in 1, 2:
539 output.append(4)
Guido van Rossumb940e112007-01-10 16:19:56 +0000540 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000541 output.append('into' in str(e))
542
543no_jump_forwards_into_block.jump = (2, 4)
544no_jump_forwards_into_block.output = [True]
545
546def no_jump_backwards_into_block(output):
547 try:
548 for i in 1, 2:
549 output.append(3)
550 output.append(4)
Guido van Rossumb940e112007-01-10 16:19:56 +0000551 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000552 output.append('into' in str(e))
553
554no_jump_backwards_into_block.jump = (4, 3)
555no_jump_backwards_into_block.output = [3, 3, True]
556
557def no_jump_into_finally_block(output):
558 try:
559 try:
560 output.append(3)
561 x = 1
562 finally:
563 output.append(6)
Guido van Rossumb940e112007-01-10 16:19:56 +0000564 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000565 output.append('finally' in str(e))
566
567no_jump_into_finally_block.jump = (4, 6)
568no_jump_into_finally_block.output = [3, 6, True] # The 'finally' still runs
569
570def no_jump_out_of_finally_block(output):
571 try:
572 try:
573 output.append(3)
574 finally:
575 output.append(5)
576 output.append(6)
Guido van Rossumb940e112007-01-10 16:19:56 +0000577 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000578 output.append('finally' in str(e))
579
580no_jump_out_of_finally_block.jump = (5, 1)
581no_jump_out_of_finally_block.output = [3, True]
582
583# This verifies the line-numbers-must-be-integers rule.
584def no_jump_to_non_integers(output):
585 try:
586 output.append(2)
Guido van Rossumb940e112007-01-10 16:19:56 +0000587 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000588 output.append('integer' in str(e))
589
590no_jump_to_non_integers.jump = (2, "Spam")
591no_jump_to_non_integers.output = [True]
592
593# This verifies that you can't set f_lineno via _getframe or similar
594# trickery.
595def no_jump_without_trace_function():
596 try:
597 previous_frame = sys._getframe().f_back
598 previous_frame.f_lineno = previous_frame.f_lineno
Guido van Rossumb940e112007-01-10 16:19:56 +0000599 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000600 # This is the exception we wanted; make sure the error message
601 # talks about trace functions.
602 if 'trace' not in str(e):
603 raise
604 else:
605 # Something's wrong - the expected exception wasn't raised.
Collin Winter3add4d72007-08-29 23:37:32 +0000606 raise RuntimeError("Trace-function-less jump failed to fail")
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000607
608
609class JumpTestCase(unittest.TestCase):
610 def compare_jump_output(self, expected, received):
611 if received != expected:
612 self.fail( "Outputs don't match:\n" +
613 "Expected: " + repr(expected) + "\n" +
614 "Received: " + repr(received))
615
616 def run_test(self, func):
617 tracer = JumpTracer(func)
618 sys.settrace(tracer.trace)
619 output = []
620 func(output)
621 sys.settrace(None)
622 self.compare_jump_output(func.output, output)
623
624 def test_01_jump_simple_forwards(self):
625 self.run_test(jump_simple_forwards)
626 def test_02_jump_simple_backwards(self):
627 self.run_test(jump_simple_backwards)
628 def test_03_jump_out_of_block_forwards(self):
629 self.run_test(jump_out_of_block_forwards)
630 def test_04_jump_out_of_block_backwards(self):
631 self.run_test(jump_out_of_block_backwards)
632 def test_05_jump_to_codeless_line(self):
633 self.run_test(jump_to_codeless_line)
634 def test_06_jump_to_same_line(self):
635 self.run_test(jump_to_same_line)
636 def test_07_jump_in_nested_finally(self):
637 self.run_test(jump_in_nested_finally)
638 def test_08_no_jump_too_far_forwards(self):
639 self.run_test(no_jump_too_far_forwards)
640 def test_09_no_jump_too_far_backwards(self):
641 self.run_test(no_jump_too_far_backwards)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000642 def test_10_no_jump_to_except_1(self):
643 self.run_test(no_jump_to_except_1)
644 def test_11_no_jump_to_except_2(self):
645 self.run_test(no_jump_to_except_2)
646 def test_12_no_jump_to_except_3(self):
647 self.run_test(no_jump_to_except_3)
648 def test_13_no_jump_to_except_4(self):
649 self.run_test(no_jump_to_except_4)
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000650 def test_14_no_jump_forwards_into_block(self):
651 self.run_test(no_jump_forwards_into_block)
652 def test_15_no_jump_backwards_into_block(self):
653 self.run_test(no_jump_backwards_into_block)
654 def test_16_no_jump_into_finally_block(self):
655 self.run_test(no_jump_into_finally_block)
656 def test_17_no_jump_out_of_finally_block(self):
657 self.run_test(no_jump_out_of_finally_block)
658 def test_18_no_jump_to_non_integers(self):
659 self.run_test(no_jump_to_non_integers)
660 def test_19_no_jump_without_trace_function(self):
661 no_jump_without_trace_function()
662
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000663def test_main():
Walter Dörwald21d3a322003-05-01 17:45:56 +0000664 test_support.run_unittest(
665 TraceTestCase,
666 RaisingTraceFuncTestCase,
667 JumpTestCase
668 )
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000669
670if __name__ == "__main__":
671 test_main()