blob: a0f76c68fcfe3d6e9523ed7ab8bb140a420dbe2c [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
Christian Heimes9bd667a2008-01-20 15:14:11 +0000271 def set_and_retrieve_none(self):
272 sys.settrace(None)
273 assert sys.gettrace() is None
274
275 def set_and_retrieve_func(self):
276 def fn(*args):
277 pass
278
279 sys.settrace(fn)
280 try:
281 assert sys.gettrace() is fn
282 finally:
283 sys.settrace(None)
284
Nicholas Bastinaea94592004-03-22 18:30:42 +0000285 def test_01_basic(self):
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000286 self.run_test(basic)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000287 def test_02_arigo(self):
288 self.run_test(arigo_example)
Nicholas Bastinaea94592004-03-22 18:30:42 +0000289 def test_03_one_instr(self):
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000290 self.run_test(one_instr_line)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000291 def test_04_no_pop_blocks(self):
292 self.run_test(no_pop_blocks)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000293 def test_05_no_pop_tops(self):
294 self.run_test(no_pop_tops)
Nicholas Bastinaea94592004-03-22 18:30:42 +0000295 def test_06_call(self):
Michael W. Hudson519a3422002-09-11 14:47:51 +0000296 self.run_test(call)
Nicholas Bastinaea94592004-03-22 18:30:42 +0000297 def test_07_raise(self):
Michael W. Hudson519a3422002-09-11 14:47:51 +0000298 self.run_test(test_raise)
299
Nicholas Bastinaea94592004-03-22 18:30:42 +0000300 def test_08_settrace_and_return(self):
Michael W. Hudson519a3422002-09-11 14:47:51 +0000301 self.run_test2(settrace_and_return)
Nicholas Bastinaea94592004-03-22 18:30:42 +0000302 def test_09_settrace_and_raise(self):
Michael W. Hudson519a3422002-09-11 14:47:51 +0000303 self.run_test2(settrace_and_raise)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000304 def test_10_ireturn(self):
305 self.run_test(ireturn_example)
Nicholas Bastinfa7bec72004-03-22 19:21:47 +0000306 def test_11_tightloop(self):
307 self.run_test(tightloop_example)
Armin Rigo70693382004-03-22 19:30:39 +0000308 def test_12_tighterloop(self):
309 self.run_test(tighterloop_example)
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000310
Amaury Forgeot d'Arcf05149a2007-11-13 01:05:30 +0000311 def test_13_genexp(self):
312 self.run_test(generator_example)
313 # issue1265: if the trace function contains a generator,
314 # and if the traced function contains another generator
315 # that is not completely exhausted, the trace stopped.
316 # Worse: the 'finally' clause was not invoked.
317 tracer = Tracer()
318 sys.settrace(tracer.traceWithGenexp)
319 generator_example()
320 sys.settrace(None)
321 self.compare_events(generator_example.__code__.co_firstlineno,
322 tracer.events, generator_example.events)
323
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000324class RaisingTraceFuncTestCase(unittest.TestCase):
Michael W. Hudson006c7522002-11-08 13:08:46 +0000325 def trace(self, frame, event, arg):
326 """A trace function that raises an exception in response to a
327 specific trace event."""
328 if event == self.raiseOnEvent:
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000329 raise ValueError # just something that isn't RuntimeError
Michael W. Hudson006c7522002-11-08 13:08:46 +0000330 else:
331 return self.trace
Tim Peters3de75262002-11-09 05:26:15 +0000332
Michael W. Hudson006c7522002-11-08 13:08:46 +0000333 def f(self):
334 """The function to trace; raises an exception if that's the case
335 we're testing, so that the 'exception' trace event fires."""
336 if self.raiseOnEvent == 'exception':
337 x = 0
338 y = 1/x
339 else:
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000340 return 1
Tim Peters3de75262002-11-09 05:26:15 +0000341
Michael W. Hudson006c7522002-11-08 13:08:46 +0000342 def run_test_for_event(self, event):
343 """Tests that an exception raised in response to the given event is
344 handled OK."""
345 self.raiseOnEvent = event
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000346 try:
Guido van Rossum805365e2007-05-07 22:24:25 +0000347 for i in range(sys.getrecursionlimit() + 1):
Michael W. Hudson006c7522002-11-08 13:08:46 +0000348 sys.settrace(self.trace)
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000349 try:
Michael W. Hudson006c7522002-11-08 13:08:46 +0000350 self.f()
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000351 except ValueError:
352 pass
353 else:
354 self.fail("exception not thrown!")
355 except RuntimeError:
356 self.fail("recursion counter not reset")
Tim Peters3de75262002-11-09 05:26:15 +0000357
Michael W. Hudson006c7522002-11-08 13:08:46 +0000358 # Test the handling of exceptions raised by each kind of trace event.
359 def test_call(self):
360 self.run_test_for_event('call')
361 def test_line(self):
362 self.run_test_for_event('line')
363 def test_return(self):
364 self.run_test_for_event('return')
365 def test_exception(self):
366 self.run_test_for_event('exception')
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000367
Michael W. Hudson58ee2af2003-04-29 16:18:47 +0000368 def test_trash_stack(self):
369 def f():
370 for i in range(5):
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000371 print(i) # line tracing will raise an exception at this line
Michael W. Hudson58ee2af2003-04-29 16:18:47 +0000372
373 def g(frame, why, extra):
374 if (why == 'line' and
Neal Norwitz221085d2007-02-25 20:55:47 +0000375 frame.f_lineno == f.__code__.co_firstlineno + 2):
Collin Winter3add4d72007-08-29 23:37:32 +0000376 raise RuntimeError("i am crashing")
Michael W. Hudson58ee2af2003-04-29 16:18:47 +0000377 return g
378
379 sys.settrace(g)
380 try:
381 f()
382 except RuntimeError:
383 # the test is really that this doesn't segfault:
384 import gc
385 gc.collect()
386 else:
387 self.fail("exception not propagated")
388
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000389
390# 'Jump' tests: assigning to frame.f_lineno within a trace function
391# moves the execution position - it's how debuggers implement a Jump
392# command (aka. "Set next statement").
393
394class JumpTracer:
395 """Defines a trace function that jumps from one place to another,
396 with the source and destination lines of the jump being defined by
397 the 'jump' property of the function under test."""
398
399 def __init__(self, function):
400 self.function = function
401 self.jumpFrom = function.jump[0]
402 self.jumpTo = function.jump[1]
403 self.done = False
404
405 def trace(self, frame, event, arg):
Neal Norwitz221085d2007-02-25 20:55:47 +0000406 if not self.done and frame.f_code == self.function.__code__:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000407 firstLine = frame.f_code.co_firstlineno
408 if frame.f_lineno == firstLine + self.jumpFrom:
409 # Cope with non-integer self.jumpTo (because of
410 # no_jump_to_non_integers below).
411 try:
412 frame.f_lineno = firstLine + self.jumpTo
413 except TypeError:
414 frame.f_lineno = self.jumpTo
415 self.done = True
416 return self.trace
417
418# The first set of 'jump' tests are for things that are allowed:
419
420def jump_simple_forwards(output):
421 output.append(1)
422 output.append(2)
423 output.append(3)
424
425jump_simple_forwards.jump = (1, 3)
426jump_simple_forwards.output = [3]
427
428def jump_simple_backwards(output):
429 output.append(1)
430 output.append(2)
431
432jump_simple_backwards.jump = (2, 1)
433jump_simple_backwards.output = [1, 1, 2]
434
435def jump_out_of_block_forwards(output):
436 for i in 1, 2:
437 output.append(2)
438 for j in [3]: # Also tests jumping over a block
439 output.append(4)
440 output.append(5)
441
442jump_out_of_block_forwards.jump = (3, 5)
443jump_out_of_block_forwards.output = [2, 5]
444
445def jump_out_of_block_backwards(output):
446 output.append(1)
447 for i in [1]:
448 output.append(3)
449 for j in [2]: # Also tests jumping over a block
450 output.append(5)
451 output.append(6)
452 output.append(7)
453
454jump_out_of_block_backwards.jump = (6, 1)
455jump_out_of_block_backwards.output = [1, 3, 5, 1, 3, 5, 6, 7]
456
457def jump_to_codeless_line(output):
458 output.append(1)
459 # Jumping to this line should skip to the next one.
460 output.append(3)
461
462jump_to_codeless_line.jump = (1, 2)
463jump_to_codeless_line.output = [3]
464
465def jump_to_same_line(output):
466 output.append(1)
467 output.append(2)
468 output.append(3)
469
470jump_to_same_line.jump = (2, 2)
471jump_to_same_line.output = [1, 2, 3]
472
473# Tests jumping within a finally block, and over one.
474def jump_in_nested_finally(output):
475 try:
476 output.append(2)
477 finally:
478 output.append(4)
479 try:
480 output.append(6)
481 finally:
482 output.append(8)
483 output.append(9)
484
485jump_in_nested_finally.jump = (4, 9)
486jump_in_nested_finally.output = [2, 9]
487
488# The second set of 'jump' tests are for things that are not allowed:
489
490def no_jump_too_far_forwards(output):
491 try:
492 output.append(2)
493 output.append(3)
Guido van Rossumb940e112007-01-10 16:19:56 +0000494 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000495 output.append('after' in str(e))
496
497no_jump_too_far_forwards.jump = (3, 6)
498no_jump_too_far_forwards.output = [2, True]
499
500def no_jump_too_far_backwards(output):
501 try:
502 output.append(2)
503 output.append(3)
Guido van Rossumb940e112007-01-10 16:19:56 +0000504 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000505 output.append('before' in str(e))
506
507no_jump_too_far_backwards.jump = (3, -1)
508no_jump_too_far_backwards.output = [2, True]
509
510# Test each kind of 'except' line.
511def no_jump_to_except_1(output):
512 try:
513 output.append(2)
514 except:
515 e = sys.exc_info()[1]
516 output.append('except' in str(e))
517
518no_jump_to_except_1.jump = (2, 3)
519no_jump_to_except_1.output = [True]
520
521def no_jump_to_except_2(output):
522 try:
523 output.append(2)
524 except ValueError:
525 e = sys.exc_info()[1]
526 output.append('except' in str(e))
527
528no_jump_to_except_2.jump = (2, 3)
529no_jump_to_except_2.output = [True]
530
531def no_jump_to_except_3(output):
532 try:
533 output.append(2)
Guido van Rossumb940e112007-01-10 16:19:56 +0000534 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000535 output.append('except' in str(e))
536
537no_jump_to_except_3.jump = (2, 3)
538no_jump_to_except_3.output = [True]
539
540def no_jump_to_except_4(output):
541 try:
542 output.append(2)
Guido van Rossumb940e112007-01-10 16:19:56 +0000543 except (ValueError, RuntimeError) as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000544 output.append('except' in str(e))
545
546no_jump_to_except_4.jump = (2, 3)
547no_jump_to_except_4.output = [True]
548
549def no_jump_forwards_into_block(output):
550 try:
551 output.append(2)
552 for i in 1, 2:
553 output.append(4)
Guido van Rossumb940e112007-01-10 16:19:56 +0000554 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000555 output.append('into' in str(e))
556
557no_jump_forwards_into_block.jump = (2, 4)
558no_jump_forwards_into_block.output = [True]
559
560def no_jump_backwards_into_block(output):
561 try:
562 for i in 1, 2:
563 output.append(3)
564 output.append(4)
Guido van Rossumb940e112007-01-10 16:19:56 +0000565 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000566 output.append('into' in str(e))
567
568no_jump_backwards_into_block.jump = (4, 3)
569no_jump_backwards_into_block.output = [3, 3, True]
570
571def no_jump_into_finally_block(output):
572 try:
573 try:
574 output.append(3)
575 x = 1
576 finally:
577 output.append(6)
Guido van Rossumb940e112007-01-10 16:19:56 +0000578 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000579 output.append('finally' in str(e))
580
581no_jump_into_finally_block.jump = (4, 6)
582no_jump_into_finally_block.output = [3, 6, True] # The 'finally' still runs
583
584def no_jump_out_of_finally_block(output):
585 try:
586 try:
587 output.append(3)
588 finally:
589 output.append(5)
590 output.append(6)
Guido van Rossumb940e112007-01-10 16:19:56 +0000591 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000592 output.append('finally' in str(e))
593
594no_jump_out_of_finally_block.jump = (5, 1)
595no_jump_out_of_finally_block.output = [3, True]
596
597# This verifies the line-numbers-must-be-integers rule.
598def no_jump_to_non_integers(output):
599 try:
600 output.append(2)
Guido van Rossumb940e112007-01-10 16:19:56 +0000601 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000602 output.append('integer' in str(e))
603
604no_jump_to_non_integers.jump = (2, "Spam")
605no_jump_to_non_integers.output = [True]
606
607# This verifies that you can't set f_lineno via _getframe or similar
608# trickery.
609def no_jump_without_trace_function():
610 try:
611 previous_frame = sys._getframe().f_back
612 previous_frame.f_lineno = previous_frame.f_lineno
Guido van Rossumb940e112007-01-10 16:19:56 +0000613 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000614 # This is the exception we wanted; make sure the error message
615 # talks about trace functions.
616 if 'trace' not in str(e):
617 raise
618 else:
619 # Something's wrong - the expected exception wasn't raised.
Collin Winter3add4d72007-08-29 23:37:32 +0000620 raise RuntimeError("Trace-function-less jump failed to fail")
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000621
622
623class JumpTestCase(unittest.TestCase):
624 def compare_jump_output(self, expected, received):
625 if received != expected:
626 self.fail( "Outputs don't match:\n" +
627 "Expected: " + repr(expected) + "\n" +
628 "Received: " + repr(received))
629
630 def run_test(self, func):
631 tracer = JumpTracer(func)
632 sys.settrace(tracer.trace)
633 output = []
634 func(output)
635 sys.settrace(None)
636 self.compare_jump_output(func.output, output)
637
638 def test_01_jump_simple_forwards(self):
639 self.run_test(jump_simple_forwards)
640 def test_02_jump_simple_backwards(self):
641 self.run_test(jump_simple_backwards)
642 def test_03_jump_out_of_block_forwards(self):
643 self.run_test(jump_out_of_block_forwards)
644 def test_04_jump_out_of_block_backwards(self):
645 self.run_test(jump_out_of_block_backwards)
646 def test_05_jump_to_codeless_line(self):
647 self.run_test(jump_to_codeless_line)
648 def test_06_jump_to_same_line(self):
649 self.run_test(jump_to_same_line)
650 def test_07_jump_in_nested_finally(self):
651 self.run_test(jump_in_nested_finally)
652 def test_08_no_jump_too_far_forwards(self):
653 self.run_test(no_jump_too_far_forwards)
654 def test_09_no_jump_too_far_backwards(self):
655 self.run_test(no_jump_too_far_backwards)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000656 def test_10_no_jump_to_except_1(self):
657 self.run_test(no_jump_to_except_1)
658 def test_11_no_jump_to_except_2(self):
659 self.run_test(no_jump_to_except_2)
660 def test_12_no_jump_to_except_3(self):
661 self.run_test(no_jump_to_except_3)
662 def test_13_no_jump_to_except_4(self):
663 self.run_test(no_jump_to_except_4)
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000664 def test_14_no_jump_forwards_into_block(self):
665 self.run_test(no_jump_forwards_into_block)
666 def test_15_no_jump_backwards_into_block(self):
667 self.run_test(no_jump_backwards_into_block)
668 def test_16_no_jump_into_finally_block(self):
669 self.run_test(no_jump_into_finally_block)
670 def test_17_no_jump_out_of_finally_block(self):
671 self.run_test(no_jump_out_of_finally_block)
672 def test_18_no_jump_to_non_integers(self):
673 self.run_test(no_jump_to_non_integers)
674 def test_19_no_jump_without_trace_function(self):
675 no_jump_without_trace_function()
676
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000677def test_main():
Walter Dörwald21d3a322003-05-01 17:45:56 +0000678 test_support.run_unittest(
679 TraceTestCase,
680 RaisingTraceFuncTestCase,
681 JumpTestCase
682 )
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000683
684if __name__ == "__main__":
685 test_main()