blob: 43134e98bd49beee75eab8b428596ccb6107555f [file] [log] [blame]
Michael W. Hudson53d58bb2002-08-30 13:09:51 +00001# Testing the line trace facility.
2
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003from test import support
Michael W. Hudson53d58bb2002-08-30 13:09:51 +00004import unittest
5import sys
6import difflib
Christian Heimes81ee3ef2008-05-04 22:42:01 +00007import gc
Michael W. Hudson53d58bb2002-08-30 13:09:51 +00008
9# A very basic example. If this fails, we're in deep trouble.
10def basic():
11 return 1
12
13basic.events = [(0, 'call'),
14 (1, 'line'),
15 (1, 'return')]
16
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000017# 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".
Michael W. Hudson53d58bb2002-08-30 13:09:51 +000026def arigo_example():
27 x = 1
28 del x
29 while 0:
30 pass
31 x = 1
32
33arigo_example.events = [(0, 'call'),
34 (1, 'line'),
35 (2, 'line'),
Michael W. Hudson53d58bb2002-08-30 13:09:51 +000036 (5, 'line'),
37 (5, 'return')]
38
39# check that lines consisting of just one instruction get traced:
40def one_instr_line():
41 x = 1
42 del x
43 x = 1
44
45one_instr_line.events = [(0, 'call'),
46 (1, 'line'),
47 (2, 'line'),
48 (3, 'line'),
49 (3, 'return')]
50
51def no_pop_tops(): # 0
52 x = 1 # 1
53 for a in range(2): # 2
54 if a: # 3
55 x = 1 # 4
56 else: # 5
57 x = 1 # 6
58
59no_pop_tops.events = [(0, 'call'),
60 (1, 'line'),
61 (2, 'line'),
62 (3, 'line'),
63 (6, 'line'),
64 (2, 'line'),
65 (3, 'line'),
66 (4, 'line'),
67 (2, 'line'),
Michael W. Hudson02ff6a92002-09-11 15:36:32 +000068 (2, 'return')]
Michael W. Hudson53d58bb2002-08-30 13:09:51 +000069
70def no_pop_blocks():
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000071 y = 1
72 while not y:
Michael W. Hudson53d58bb2002-08-30 13:09:51 +000073 bla
74 x = 1
75
76no_pop_blocks.events = [(0, 'call'),
77 (1, 'line'),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000078 (2, 'line'),
79 (4, 'line'),
80 (4, 'return')]
Michael W. Hudson53d58bb2002-08-30 13:09:51 +000081
Michael W. Hudson519a3422002-09-11 14:47:51 +000082def called(): # line -3
83 x = 1
84
85def call(): # line 0
86 called()
87
88call.events = [(0, 'call'),
89 (1, 'line'),
90 (-3, 'call'),
91 (-2, 'line'),
92 (-2, 'return'),
93 (1, 'return')]
94
95def raises():
96 raise Exception
97
98def test_raise():
99 try:
100 raises()
Guido van Rossumb940e112007-01-10 16:19:56 +0000101 except Exception as exc:
Michael W. Hudson519a3422002-09-11 14:47:51 +0000102 x = 1
103
104test_raise.events = [(0, 'call'),
105 (1, 'line'),
106 (2, 'line'),
107 (-3, 'call'),
108 (-2, 'line'),
109 (-2, 'exception'),
Barry Warsawe2eca0b2005-08-15 18:14:19 +0000110 (-2, 'return'),
Michael W. Hudson519a3422002-09-11 14:47:51 +0000111 (2, 'exception'),
112 (3, 'line'),
113 (4, 'line'),
114 (4, 'return')]
115
116def _settrace_and_return(tracefunc):
117 sys.settrace(tracefunc)
118 sys._getframe().f_back.f_trace = tracefunc
119def settrace_and_return(tracefunc):
120 _settrace_and_return(tracefunc)
Tim Peters3de75262002-11-09 05:26:15 +0000121
Michael W. Hudson519a3422002-09-11 14:47:51 +0000122settrace_and_return.events = [(1, 'return')]
123
124def _settrace_and_raise(tracefunc):
125 sys.settrace(tracefunc)
126 sys._getframe().f_back.f_trace = tracefunc
127 raise RuntimeError
128def settrace_and_raise(tracefunc):
129 try:
130 _settrace_and_raise(tracefunc)
Guido van Rossumb940e112007-01-10 16:19:56 +0000131 except RuntimeError as exc:
Michael W. Hudson519a3422002-09-11 14:47:51 +0000132 pass
Tim Peters3de75262002-11-09 05:26:15 +0000133
Michael W. Hudson519a3422002-09-11 14:47:51 +0000134settrace_and_raise.events = [(2, 'exception'),
135 (3, 'line'),
136 (4, 'line'),
137 (4, 'return')]
138
Nicholas Bastinaea94592004-03-22 18:30:42 +0000139# implicit return example
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000140# 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.
Nicholas Bastinaea94592004-03-22 18:30:42 +0000147def ireturn_example():
148 a = 5
149 b = 5
150 if a == b:
151 b = a+1
152 else:
153 pass
154
155ireturn_example.events = [(0, 'call'),
156 (1, 'line'),
157 (2, 'line'),
158 (3, 'line'),
159 (4, 'line'),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000160 (6, 'line'),
161 (6, 'return')]
Nicholas Bastinaea94592004-03-22 18:30:42 +0000162
Nicholas Bastinfa7bec72004-03-22 19:21:47 +0000163# Tight loop with while(1) example (SF #765624)
164def tightloop_example():
165 items = range(0, 3)
166 try:
167 i = 0
168 while 1:
Nicholas Bastinee6c9b82004-03-22 19:23:46 +0000169 b = items[i]; i+=1
Nicholas Bastinfa7bec72004-03-22 19:21:47 +0000170 except IndexError:
171 pass
172
173tightloop_example.events = [(0, 'call'),
174 (1, 'line'),
175 (2, 'line'),
176 (3, 'line'),
177 (4, 'line'),
178 (5, 'line'),
179 (5, 'line'),
180 (5, 'line'),
Nicholas Bastinee6c9b82004-03-22 19:23:46 +0000181 (5, 'line'),
Nicholas Bastinfa7bec72004-03-22 19:21:47 +0000182 (5, 'exception'),
183 (6, 'line'),
184 (7, 'line'),
185 (7, 'return')]
186
Armin Rigo70693382004-03-22 19:30:39 +0000187def tighterloop_example():
188 items = range(1, 4)
189 try:
190 i = 0
191 while 1: i = items[i]
192 except IndexError:
193 pass
194
195tighterloop_example.events = [(0, 'call'),
196 (1, 'line'),
197 (2, 'line'),
198 (3, 'line'),
199 (4, 'line'),
200 (4, 'line'),
201 (4, 'line'),
202 (4, 'line'),
203 (4, 'exception'),
204 (5, 'line'),
205 (6, 'line'),
206 (6, 'return')]
207
Amaury Forgeot d'Arcf05149a2007-11-13 01:05:30 +0000208def generator_function():
209 try:
210 yield True
211 "continued"
212 finally:
213 "finally"
214def generator_example():
215 # any() will leave the generator before its end
216 x = any(generator_function())
217
218 # the following lines were not traced
219 for x in range(10):
220 y = x
221
222generator_example.events = ([(0, 'call'),
223 (2, 'line'),
224 (-6, 'call'),
225 (-5, 'line'),
226 (-4, 'line'),
227 (-4, 'return'),
228 (-4, 'call'),
229 (-4, 'exception'),
230 (-1, 'line'),
231 (-1, 'return')] +
232 [(5, 'line'), (6, 'line')] * 10 +
233 [(5, 'line'), (5, 'return')])
234
235
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000236class 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
Amaury Forgeot d'Arcf05149a2007-11-13 01:05:30 +0000242 def traceWithGenexp(self, frame, event, arg):
243 (o for o in [1])
244 self.events.append((frame.f_lineno, event))
245 return self.trace
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000246
247class TraceTestCase(unittest.TestCase):
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000248
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
Michael W. Hudson519a3422002-09-11 14:47:51 +0000259 def compare_events(self, line_offset, events, expected_events):
Tim Peters3de75262002-11-09 05:26:15 +0000260 events = [(l - line_offset, e) for (l, e) in events]
Michael W. Hudson519a3422002-09-11 14:47:51 +0000261 if events != expected_events:
262 self.fail(
263 "events did not match expectation:\n" +
Amaury Forgeot d'Arcf05149a2007-11-13 01:05:30 +0000264 "\n".join(difflib.ndiff([str(x) for x in expected_events],
265 [str(x) for x in events])))
Tim Peters3de75262002-11-09 05:26:15 +0000266
Christian Heimes2202f872008-02-06 14:31:34 +0000267 def run_and_compare(self, func, events):
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000268 tracer = Tracer()
269 sys.settrace(tracer.trace)
270 func()
271 sys.settrace(None)
Neal Norwitz221085d2007-02-25 20:55:47 +0000272 self.compare_events(func.__code__.co_firstlineno,
Christian Heimes2202f872008-02-06 14:31:34 +0000273 tracer.events, events)
274
275 def run_test(self, func):
276 self.run_and_compare(func, func.events)
Michael W. Hudson519a3422002-09-11 14:47:51 +0000277
278 def run_test2(self, func):
279 tracer = Tracer()
280 func(tracer.trace)
281 sys.settrace(None)
Neal Norwitz221085d2007-02-25 20:55:47 +0000282 self.compare_events(func.__code__.co_firstlineno,
Michael W. Hudson519a3422002-09-11 14:47:51 +0000283 tracer.events, func.events)
Tim Peters3de75262002-11-09 05:26:15 +0000284
Christian Heimes9bd667a2008-01-20 15:14:11 +0000285 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
Nicholas Bastinaea94592004-03-22 18:30:42 +0000299 def test_01_basic(self):
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000300 self.run_test(basic)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000301 def test_02_arigo(self):
302 self.run_test(arigo_example)
Nicholas Bastinaea94592004-03-22 18:30:42 +0000303 def test_03_one_instr(self):
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000304 self.run_test(one_instr_line)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000305 def test_04_no_pop_blocks(self):
306 self.run_test(no_pop_blocks)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000307 def test_05_no_pop_tops(self):
308 self.run_test(no_pop_tops)
Nicholas Bastinaea94592004-03-22 18:30:42 +0000309 def test_06_call(self):
Michael W. Hudson519a3422002-09-11 14:47:51 +0000310 self.run_test(call)
Nicholas Bastinaea94592004-03-22 18:30:42 +0000311 def test_07_raise(self):
Michael W. Hudson519a3422002-09-11 14:47:51 +0000312 self.run_test(test_raise)
313
Nicholas Bastinaea94592004-03-22 18:30:42 +0000314 def test_08_settrace_and_return(self):
Michael W. Hudson519a3422002-09-11 14:47:51 +0000315 self.run_test2(settrace_and_return)
Nicholas Bastinaea94592004-03-22 18:30:42 +0000316 def test_09_settrace_and_raise(self):
Michael W. Hudson519a3422002-09-11 14:47:51 +0000317 self.run_test2(settrace_and_raise)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000318 def test_10_ireturn(self):
319 self.run_test(ireturn_example)
Nicholas Bastinfa7bec72004-03-22 19:21:47 +0000320 def test_11_tightloop(self):
321 self.run_test(tightloop_example)
Armin Rigo70693382004-03-22 19:30:39 +0000322 def test_12_tighterloop(self):
323 self.run_test(tighterloop_example)
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000324
Amaury Forgeot d'Arcf05149a2007-11-13 01:05:30 +0000325 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
Christian Heimes2202f872008-02-06 14:31:34 +0000338 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 namespace = {}
383 exec("def f():\n" + "\n" * 256 + " pass", namespace)
384 self.run_and_compare(
385 namespace["f"],
386 [(0, 'call'),
387 (257, 'line'),
388 (257, 'return')])
389
390
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000391class RaisingTraceFuncTestCase(unittest.TestCase):
Michael W. Hudson006c7522002-11-08 13:08:46 +0000392 def trace(self, frame, event, arg):
393 """A trace function that raises an exception in response to a
394 specific trace event."""
395 if event == self.raiseOnEvent:
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000396 raise ValueError # just something that isn't RuntimeError
Michael W. Hudson006c7522002-11-08 13:08:46 +0000397 else:
398 return self.trace
Tim Peters3de75262002-11-09 05:26:15 +0000399
Michael W. Hudson006c7522002-11-08 13:08:46 +0000400 def f(self):
401 """The function to trace; raises an exception if that's the case
402 we're testing, so that the 'exception' trace event fires."""
403 if self.raiseOnEvent == 'exception':
404 x = 0
405 y = 1/x
406 else:
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000407 return 1
Tim Peters3de75262002-11-09 05:26:15 +0000408
Michael W. Hudson006c7522002-11-08 13:08:46 +0000409 def run_test_for_event(self, event):
410 """Tests that an exception raised in response to the given event is
411 handled OK."""
412 self.raiseOnEvent = event
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000413 try:
Guido van Rossum805365e2007-05-07 22:24:25 +0000414 for i in range(sys.getrecursionlimit() + 1):
Michael W. Hudson006c7522002-11-08 13:08:46 +0000415 sys.settrace(self.trace)
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000416 try:
Michael W. Hudson006c7522002-11-08 13:08:46 +0000417 self.f()
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000418 except ValueError:
419 pass
420 else:
421 self.fail("exception not thrown!")
422 except RuntimeError:
423 self.fail("recursion counter not reset")
Tim Peters3de75262002-11-09 05:26:15 +0000424
Michael W. Hudson006c7522002-11-08 13:08:46 +0000425 # Test the handling of exceptions raised by each kind of trace event.
426 def test_call(self):
427 self.run_test_for_event('call')
428 def test_line(self):
429 self.run_test_for_event('line')
430 def test_return(self):
431 self.run_test_for_event('return')
432 def test_exception(self):
433 self.run_test_for_event('exception')
Michael W. Hudsonfb4d6ec2002-10-02 13:13:45 +0000434
Michael W. Hudson58ee2af2003-04-29 16:18:47 +0000435 def test_trash_stack(self):
436 def f():
437 for i in range(5):
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000438 print(i) # line tracing will raise an exception at this line
Michael W. Hudson58ee2af2003-04-29 16:18:47 +0000439
440 def g(frame, why, extra):
441 if (why == 'line' and
Neal Norwitz221085d2007-02-25 20:55:47 +0000442 frame.f_lineno == f.__code__.co_firstlineno + 2):
Collin Winter3add4d72007-08-29 23:37:32 +0000443 raise RuntimeError("i am crashing")
Michael W. Hudson58ee2af2003-04-29 16:18:47 +0000444 return g
445
446 sys.settrace(g)
447 try:
448 f()
449 except RuntimeError:
450 # the test is really that this doesn't segfault:
451 import gc
452 gc.collect()
453 else:
454 self.fail("exception not propagated")
455
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000456
457# 'Jump' tests: assigning to frame.f_lineno within a trace function
458# moves the execution position - it's how debuggers implement a Jump
459# command (aka. "Set next statement").
460
461class JumpTracer:
462 """Defines a trace function that jumps from one place to another,
463 with the source and destination lines of the jump being defined by
464 the 'jump' property of the function under test."""
465
466 def __init__(self, function):
467 self.function = function
468 self.jumpFrom = function.jump[0]
469 self.jumpTo = function.jump[1]
470 self.done = False
471
472 def trace(self, frame, event, arg):
Neal Norwitz221085d2007-02-25 20:55:47 +0000473 if not self.done and frame.f_code == self.function.__code__:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000474 firstLine = frame.f_code.co_firstlineno
Jeffrey Yasskin4db6ff62009-05-20 19:09:05 +0000475 if event == 'line' and frame.f_lineno == firstLine + self.jumpFrom:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000476 # Cope with non-integer self.jumpTo (because of
477 # no_jump_to_non_integers below).
478 try:
479 frame.f_lineno = firstLine + self.jumpTo
480 except TypeError:
481 frame.f_lineno = self.jumpTo
482 self.done = True
483 return self.trace
484
485# The first set of 'jump' tests are for things that are allowed:
486
487def jump_simple_forwards(output):
488 output.append(1)
489 output.append(2)
490 output.append(3)
491
492jump_simple_forwards.jump = (1, 3)
493jump_simple_forwards.output = [3]
494
495def jump_simple_backwards(output):
496 output.append(1)
497 output.append(2)
498
499jump_simple_backwards.jump = (2, 1)
500jump_simple_backwards.output = [1, 1, 2]
501
502def jump_out_of_block_forwards(output):
503 for i in 1, 2:
504 output.append(2)
505 for j in [3]: # Also tests jumping over a block
506 output.append(4)
507 output.append(5)
508
509jump_out_of_block_forwards.jump = (3, 5)
510jump_out_of_block_forwards.output = [2, 5]
511
512def jump_out_of_block_backwards(output):
513 output.append(1)
514 for i in [1]:
515 output.append(3)
516 for j in [2]: # Also tests jumping over a block
517 output.append(5)
518 output.append(6)
519 output.append(7)
520
521jump_out_of_block_backwards.jump = (6, 1)
522jump_out_of_block_backwards.output = [1, 3, 5, 1, 3, 5, 6, 7]
523
524def jump_to_codeless_line(output):
525 output.append(1)
526 # Jumping to this line should skip to the next one.
527 output.append(3)
528
529jump_to_codeless_line.jump = (1, 2)
530jump_to_codeless_line.output = [3]
531
532def jump_to_same_line(output):
533 output.append(1)
534 output.append(2)
535 output.append(3)
536
537jump_to_same_line.jump = (2, 2)
538jump_to_same_line.output = [1, 2, 3]
539
540# Tests jumping within a finally block, and over one.
541def jump_in_nested_finally(output):
542 try:
543 output.append(2)
544 finally:
545 output.append(4)
546 try:
547 output.append(6)
548 finally:
549 output.append(8)
550 output.append(9)
551
552jump_in_nested_finally.jump = (4, 9)
553jump_in_nested_finally.output = [2, 9]
554
555# The second set of 'jump' tests are for things that are not allowed:
556
557def no_jump_too_far_forwards(output):
558 try:
559 output.append(2)
560 output.append(3)
Guido van Rossumb940e112007-01-10 16:19:56 +0000561 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000562 output.append('after' in str(e))
563
564no_jump_too_far_forwards.jump = (3, 6)
565no_jump_too_far_forwards.output = [2, True]
566
567def no_jump_too_far_backwards(output):
568 try:
569 output.append(2)
570 output.append(3)
Guido van Rossumb940e112007-01-10 16:19:56 +0000571 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000572 output.append('before' in str(e))
573
574no_jump_too_far_backwards.jump = (3, -1)
575no_jump_too_far_backwards.output = [2, True]
576
577# Test each kind of 'except' line.
578def no_jump_to_except_1(output):
579 try:
580 output.append(2)
581 except:
582 e = sys.exc_info()[1]
583 output.append('except' in str(e))
584
585no_jump_to_except_1.jump = (2, 3)
586no_jump_to_except_1.output = [True]
587
588def no_jump_to_except_2(output):
589 try:
590 output.append(2)
591 except ValueError:
592 e = sys.exc_info()[1]
593 output.append('except' in str(e))
594
595no_jump_to_except_2.jump = (2, 3)
596no_jump_to_except_2.output = [True]
597
598def no_jump_to_except_3(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('except' in str(e))
603
604no_jump_to_except_3.jump = (2, 3)
605no_jump_to_except_3.output = [True]
606
607def no_jump_to_except_4(output):
608 try:
609 output.append(2)
Guido van Rossumb940e112007-01-10 16:19:56 +0000610 except (ValueError, RuntimeError) as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000611 output.append('except' in str(e))
612
613no_jump_to_except_4.jump = (2, 3)
614no_jump_to_except_4.output = [True]
615
616def no_jump_forwards_into_block(output):
617 try:
618 output.append(2)
619 for i in 1, 2:
620 output.append(4)
Guido van Rossumb940e112007-01-10 16:19:56 +0000621 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000622 output.append('into' in str(e))
623
624no_jump_forwards_into_block.jump = (2, 4)
625no_jump_forwards_into_block.output = [True]
626
627def no_jump_backwards_into_block(output):
628 try:
629 for i in 1, 2:
630 output.append(3)
631 output.append(4)
Guido van Rossumb940e112007-01-10 16:19:56 +0000632 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000633 output.append('into' in str(e))
634
635no_jump_backwards_into_block.jump = (4, 3)
636no_jump_backwards_into_block.output = [3, 3, True]
637
638def no_jump_into_finally_block(output):
639 try:
640 try:
641 output.append(3)
642 x = 1
643 finally:
644 output.append(6)
Guido van Rossumb940e112007-01-10 16:19:56 +0000645 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000646 output.append('finally' in str(e))
647
648no_jump_into_finally_block.jump = (4, 6)
649no_jump_into_finally_block.output = [3, 6, True] # The 'finally' still runs
650
651def no_jump_out_of_finally_block(output):
652 try:
653 try:
654 output.append(3)
655 finally:
656 output.append(5)
657 output.append(6)
Guido van Rossumb940e112007-01-10 16:19:56 +0000658 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000659 output.append('finally' in str(e))
660
661no_jump_out_of_finally_block.jump = (5, 1)
662no_jump_out_of_finally_block.output = [3, True]
663
664# This verifies the line-numbers-must-be-integers rule.
665def no_jump_to_non_integers(output):
666 try:
667 output.append(2)
Guido van Rossumb940e112007-01-10 16:19:56 +0000668 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000669 output.append('integer' in str(e))
670
671no_jump_to_non_integers.jump = (2, "Spam")
672no_jump_to_non_integers.output = [True]
673
674# This verifies that you can't set f_lineno via _getframe or similar
675# trickery.
676def no_jump_without_trace_function():
677 try:
678 previous_frame = sys._getframe().f_back
679 previous_frame.f_lineno = previous_frame.f_lineno
Guido van Rossumb940e112007-01-10 16:19:56 +0000680 except ValueError as e:
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000681 # This is the exception we wanted; make sure the error message
682 # talks about trace functions.
683 if 'trace' not in str(e):
684 raise
685 else:
686 # Something's wrong - the expected exception wasn't raised.
Collin Winter3add4d72007-08-29 23:37:32 +0000687 raise RuntimeError("Trace-function-less jump failed to fail")
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000688
689
690class JumpTestCase(unittest.TestCase):
691 def compare_jump_output(self, expected, received):
692 if received != expected:
693 self.fail( "Outputs don't match:\n" +
694 "Expected: " + repr(expected) + "\n" +
695 "Received: " + repr(received))
696
697 def run_test(self, func):
698 tracer = JumpTracer(func)
699 sys.settrace(tracer.trace)
700 output = []
701 func(output)
702 sys.settrace(None)
703 self.compare_jump_output(func.output, output)
704
705 def test_01_jump_simple_forwards(self):
706 self.run_test(jump_simple_forwards)
707 def test_02_jump_simple_backwards(self):
708 self.run_test(jump_simple_backwards)
709 def test_03_jump_out_of_block_forwards(self):
710 self.run_test(jump_out_of_block_forwards)
711 def test_04_jump_out_of_block_backwards(self):
712 self.run_test(jump_out_of_block_backwards)
713 def test_05_jump_to_codeless_line(self):
714 self.run_test(jump_to_codeless_line)
715 def test_06_jump_to_same_line(self):
716 self.run_test(jump_to_same_line)
717 def test_07_jump_in_nested_finally(self):
718 self.run_test(jump_in_nested_finally)
719 def test_08_no_jump_too_far_forwards(self):
720 self.run_test(no_jump_too_far_forwards)
721 def test_09_no_jump_too_far_backwards(self):
722 self.run_test(no_jump_too_far_backwards)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000723 def test_10_no_jump_to_except_1(self):
724 self.run_test(no_jump_to_except_1)
725 def test_11_no_jump_to_except_2(self):
726 self.run_test(no_jump_to_except_2)
727 def test_12_no_jump_to_except_3(self):
728 self.run_test(no_jump_to_except_3)
729 def test_13_no_jump_to_except_4(self):
730 self.run_test(no_jump_to_except_4)
Michael W. Hudsoncfd38842002-12-17 16:15:34 +0000731 def test_14_no_jump_forwards_into_block(self):
732 self.run_test(no_jump_forwards_into_block)
733 def test_15_no_jump_backwards_into_block(self):
734 self.run_test(no_jump_backwards_into_block)
735 def test_16_no_jump_into_finally_block(self):
736 self.run_test(no_jump_into_finally_block)
737 def test_17_no_jump_out_of_finally_block(self):
738 self.run_test(no_jump_out_of_finally_block)
739 def test_18_no_jump_to_non_integers(self):
740 self.run_test(no_jump_to_non_integers)
741 def test_19_no_jump_without_trace_function(self):
742 no_jump_without_trace_function()
743
Amaury Forgeot d'Arc24e581f2009-06-01 21:28:37 +0000744 def test_20_large_function(self):
745 d = {}
746 exec("""def f(output): # line 0
747 x = 0 # line 1
748 y = 1 # line 2
749 ''' # line 3
750 %s # lines 4-1004
751 ''' # line 1005
752 x += 1 # line 1006
753 output.append(x) # line 1007
754 return""" % ('\n' * 1000,), d)
755 f = d['f']
756
757 f.jump = (2, 1007)
758 f.output = [0]
759 self.run_test(f)
760
Jeffrey Yasskin4db6ff62009-05-20 19:09:05 +0000761 def test_jump_to_firstlineno(self):
762 # This tests that PDB can jump back to the first line in a
763 # file. See issue #1689458. It can only be triggered in a
764 # function call if the function is defined on a single line.
765 code = compile("""
766# Comments don't count.
767output.append(2) # firstlineno is here.
768output.append(3)
769output.append(4)
770""", "<fake module>", "exec")
771 class fake_function:
772 __code__ = code
773 jump = (2, 0)
774 tracer = JumpTracer(fake_function)
775 sys.settrace(tracer.trace)
776 namespace = {"output": []}
777 exec(code, namespace)
778 sys.settrace(None)
779 self.compare_jump_output([2, 3, 2, 3, 4], namespace["output"])
780
781
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000782def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000783 support.run_unittest(
Walter Dörwald21d3a322003-05-01 17:45:56 +0000784 TraceTestCase,
785 RaisingTraceFuncTestCase,
786 JumpTestCase
787 )
Michael W. Hudson53d58bb2002-08-30 13:09:51 +0000788
789if __name__ == "__main__":
790 test_main()