| OLD | NEW |
| 1 # Testing the line trace facility. | 1 # Testing the line trace facility. |
| 2 | 2 |
| 3 from test import test_support | 3 from test import test_support |
| 4 import unittest | 4 import unittest |
| 5 import sys | 5 import sys |
| 6 import difflib | 6 import difflib |
| 7 | 7 |
| 8 # A very basic example. If this fails, we're in deep trouble. | 8 # A very basic example. If this fails, we're in deep trouble. |
| 9 def basic(): | 9 def basic(): |
| 10 return 1 | 10 return 1 |
| 11 | 11 |
| 12 basic.events = [(0, 'call'), | 12 basic.events = [(0, 'call'), |
| 13 (1, 'line'), | 13 (1, 'line'), |
| 14 (1, 'return')] | 14 (1, 'return')] |
| 15 | 15 |
| 16 # Many of the tests below are tricky because they involve pass statements. | 16 # 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 | 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 | 18 # clause or else caluse) under what conditions do you set a line number |
| 19 # following that clause? | 19 # following that clause? |
| 20 | 20 |
| 21 | 21 |
| 22 # The entire "while 0:" statement is optimized away. No code | 22 # The entire "while 0:" statement is optimized away. No code |
| 23 # exists for it, so the line numbers skip directly from "del x" | 23 # exists for it, so the line numbers skip directly from "del x" |
| 24 # to "x = 1". | 24 # to "x = 1". |
| 25 def arigo_example(): | 25 def arigo_example(): |
| 26 x = 1 | 26 x = 1 |
| 27 del x | 27 del x |
| 28 while 0: | 28 while 0: |
| 29 pass | 29 pass |
| 30 x = 1 | 30 x = 1 |
| 31 | 31 |
| 32 arigo_example.events = [(0, 'call'), | 32 arigo_example.events = [(0, 'call'), |
| 33 (1, 'line'), | 33 (1, 'line'), |
| 34 (2, 'line'), | 34 (2, 'line'), |
| 35 (5, 'line'), | 35 (5, 'line'), |
| 36 (5, 'return')] | 36 (5, 'return')] |
| 37 | 37 |
| 38 # check that lines consisting of just one instruction get traced: | 38 # check that lines consisting of just one instruction get traced: |
| 39 def one_instr_line(): | 39 def one_instr_line(): |
| 40 x = 1 | 40 x = 1 |
| 41 del x | 41 del x |
| 42 x = 1 | 42 x = 1 |
| 43 | 43 |
| 44 one_instr_line.events = [(0, 'call'), | 44 one_instr_line.events = [(0, 'call'), |
| 45 (1, 'line'), | 45 (1, 'line'), |
| 46 (2, 'line'), | 46 (2, 'line'), |
| 47 (3, 'line'), | 47 (3, 'line'), |
| 48 (3, 'return')] | 48 (3, 'return')] |
| 49 | 49 |
| 50 def no_pop_tops(): # 0 | 50 def no_pop_tops(): # 0 |
| (...skipping 63 matching lines...) Show 10 above Show 10 below |
| 114 | 114 |
| 115 def _settrace_and_return(tracefunc): | 115 def _settrace_and_return(tracefunc): |
| 116 sys.settrace(tracefunc) | 116 sys.settrace(tracefunc) |
| 117 sys._getframe().f_back.f_trace = tracefunc | 117 sys._getframe().f_back.f_trace = tracefunc |
| 118 def settrace_and_return(tracefunc): | 118 def settrace_and_return(tracefunc): |
| 119 _settrace_and_return(tracefunc) | 119 _settrace_and_return(tracefunc) |
| 120 | 120 |
| 121 settrace_and_return.events = [(1, 'return')] | 121 settrace_and_return.events = [(1, 'return')] |
| 122 | 122 |
| 123 def _settrace_and_raise(tracefunc): | 123 def _settrace_and_raise(tracefunc): |
| 124 sys.settrace(tracefunc) | 124 sys.settrace(tracefunc) |
| 125 sys._getframe().f_back.f_trace = tracefunc | 125 sys._getframe().f_back.f_trace = tracefunc |
| 126 raise RuntimeError | 126 raise RuntimeError |
| 127 def settrace_and_raise(tracefunc): | 127 def settrace_and_raise(tracefunc): |
| 128 try: | 128 try: |
| 129 _settrace_and_raise(tracefunc) | 129 _settrace_and_raise(tracefunc) |
| 130 except RuntimeError as exc: | 130 except RuntimeError as exc: |
| 131 pass | 131 pass |
| 132 | 132 |
| 133 settrace_and_raise.events = [(2, 'exception'), | 133 settrace_and_raise.events = [(2, 'exception'), |
| 134 (3, 'line'), | 134 (3, 'line'), |
| 135 (4, 'line'), | 135 (4, 'line'), |
| 136 (4, 'return')] | 136 (4, 'return')] |
| 137 | 137 |
| 138 # implicit return example | 138 # implicit return example |
| 139 # This test is interesting because of the else: pass | 139 # This test is interesting because of the else: pass |
| 140 # part of the code. The code generate for the true | 140 # part of the code. The code generate for the true |
| 141 # part of the if contains a jump past the else branch. | 141 # part of the if contains a jump past the else branch. |
| 142 # The compiler then generates an implicit "return None" | 142 # The compiler then generates an implicit "return None" |
| 143 # Internally, the compiler visits the pass statement | 143 # Internally, the compiler visits the pass statement |
| 144 # and stores its line number for use on the next instruction. | 144 # and stores its line number for use on the next instruction. |
| 145 # The next instruction is the implicit return None. | 145 # The next instruction is the implicit return None. |
| 146 def ireturn_example(): | 146 def ireturn_example(): |
| 147 a = 5 | 147 a = 5 |
| 148 b = 5 | 148 b = 5 |
| 149 if a == b: | 149 if a == b: |
| 150 b = a+1 | 150 b = a+1 |
| 151 else: | 151 else: |
| 152 pass | 152 pass |
| 153 | 153 |
| 154 ireturn_example.events = [(0, 'call'), | 154 ireturn_example.events = [(0, 'call'), |
| 155 (1, 'line'), | 155 (1, 'line'), |
| 156 (2, 'line'), | 156 (2, 'line'), |
| 157 (3, 'line'), | 157 (3, 'line'), |
| 158 (4, 'line'), | 158 (4, 'line'), |
| 159 (6, 'line'), | 159 (6, 'line'), |
| 160 (6, 'return')] | 160 (6, 'return')] |
| 161 | 161 |
| 162 # Tight loop with while(1) example (SF #765624) | 162 # Tight loop with while(1) example (SF #765624) |
| 163 def tightloop_example(): | 163 def tightloop_example(): |
| 164 items = range(0, 3) | 164 items = list(range(0, 3)) |
| 165 try: | 165 try: |
| 166 i = 0 | 166 i = 0 |
| 167 while 1: | 167 while 1: |
| 168 b = items[i]; i+=1 | 168 b = items[i]; i+=1 |
| 169 except IndexError: | 169 except IndexError: |
| 170 pass | 170 pass |
| 171 | 171 |
| 172 tightloop_example.events = [(0, 'call'), | 172 tightloop_example.events = [(0, 'call'), |
| 173 (1, 'line'), | 173 (1, 'line'), |
| 174 (2, 'line'), | 174 (2, 'line'), |
| 175 (3, 'line'), | 175 (3, 'line'), |
| 176 (4, 'line'), | 176 (4, 'line'), |
| 177 (5, 'line'), | 177 (5, 'line'), |
| 178 (5, 'line'), | 178 (5, 'line'), |
| 179 (5, 'line'), | 179 (5, 'line'), |
| 180 (5, 'line'), | 180 (5, 'line'), |
| 181 (5, 'exception'), | 181 (5, 'exception'), |
| 182 (6, 'line'), | 182 (6, 'line'), |
| 183 (7, 'line'), | 183 (7, 'line'), |
| 184 (7, 'return')] | 184 (7, 'return')] |
| 185 | 185 |
| 186 def tighterloop_example(): | 186 def tighterloop_example(): |
| 187 items = range(1, 4) | 187 items = list(range(1, 4)) |
| 188 try: | 188 try: |
| 189 i = 0 | 189 i = 0 |
| 190 while 1: i = items[i] | 190 while 1: i = items[i] |
| 191 except IndexError: | 191 except IndexError: |
| 192 pass | 192 pass |
| 193 | 193 |
| 194 tighterloop_example.events = [(0, 'call'), | 194 tighterloop_example.events = [(0, 'call'), |
| 195 (1, 'line'), | 195 (1, 'line'), |
| 196 (2, 'line'), | 196 (2, 'line'), |
| 197 (3, 'line'), | 197 (3, 'line'), |
| 198 (4, 'line'), | 198 (4, 'line'), |
| 199 (4, 'line'), | 199 (4, 'line'), |
| 200 (4, 'line'), | 200 (4, 'line'), |
| 201 (4, 'line'), | 201 (4, 'line'), |
| 202 (4, 'exception'), | 202 (4, 'exception'), |
| 203 (5, 'line'), | 203 (5, 'line'), |
| 204 (6, 'line'), | 204 (6, 'line'), |
| 205 (6, 'return')] | 205 (6, 'return')] |
| 206 | 206 |
| 207 def generator_function(): | 207 def generator_function(): |
| 208 try: | 208 try: |
| 209 yield True | 209 yield True |
| 210 "continued" | 210 "continued" |
| 211 finally: | 211 finally: |
| 212 "finally" | 212 "finally" |
| 213 def generator_example(): | 213 def generator_example(): |
| 214 # any() will leave the generator before its end | 214 # any() will leave the generator before its end |
| 215 x = any(generator_function()) | 215 x = any(generator_function()) |
| 216 | 216 |
| 217 # the following lines were not traced | 217 # the following lines were not traced |
| 218 for x in range(10): | 218 for x in range(10): |
| 219 y = x | 219 y = x |
| 220 | 220 |
| 221 generator_example.events = ([(0, 'call'), | 221 generator_example.events = ([(0, 'call'), |
| 222 (2, 'line'), | 222 (2, 'line'), |
| 223 (-6, 'call'), | 223 (-6, 'call'), |
| 224 (-5, 'line'), | 224 (-5, 'line'), |
| 225 (-4, 'line'), | 225 (-4, 'line'), |
| 226 (-4, 'return'), | 226 (-4, 'return'), |
| 227 (-4, 'call'), | 227 (-4, 'call'), |
| 228 (-4, 'exception'), | 228 (-4, 'exception'), |
| 229 (-1, 'line'), | 229 (-1, 'line'), |
| 230 (-1, 'return')] + | 230 (-1, 'return')] + |
| 231 [(5, 'line'), (6, 'line')] * 10 + | 231 [(5, 'line'), (6, 'line')] * 10 + |
| 232 [(5, 'line'), (5, 'return')]) | 232 [(5, 'line'), (5, 'return')]) |
| 233 | 233 |
| 234 | 234 |
| 235 class Tracer: | 235 class Tracer: |
| 236 def __init__(self): | 236 def __init__(self): |
| 237 self.events = [] | 237 self.events = [] |
| (...skipping 453 matching lines...) Show 10 above Show 10 below |
| 691 self.compare_jump_output(func.output, output) | 691 self.compare_jump_output(func.output, output) |
| 692 | 692 |
| 693 def test_01_jump_simple_forwards(self): | 693 def test_01_jump_simple_forwards(self): |
| 694 self.run_test(jump_simple_forwards) | 694 self.run_test(jump_simple_forwards) |
| 695 def test_02_jump_simple_backwards(self): | 695 def test_02_jump_simple_backwards(self): |
| 696 self.run_test(jump_simple_backwards) | 696 self.run_test(jump_simple_backwards) |
| 697 def test_03_jump_out_of_block_forwards(self): | 697 def test_03_jump_out_of_block_forwards(self): |
| 698 self.run_test(jump_out_of_block_forwards) | 698 self.run_test(jump_out_of_block_forwards) |
| 699 def test_04_jump_out_of_block_backwards(self): | 699 def test_04_jump_out_of_block_backwards(self): |
| 700 self.run_test(jump_out_of_block_backwards) | 700 self.run_test(jump_out_of_block_backwards) |
| 701 def test_05_jump_to_codeless_line(self): | 701 def test_05_jump_to_codeless_line(self): |
| 702 self.run_test(jump_to_codeless_line) | 702 self.run_test(jump_to_codeless_line) |
| 703 def test_06_jump_to_same_line(self): | 703 def test_06_jump_to_same_line(self): |
| 704 self.run_test(jump_to_same_line) | 704 self.run_test(jump_to_same_line) |
| 705 def test_07_jump_in_nested_finally(self): | 705 def test_07_jump_in_nested_finally(self): |
| 706 self.run_test(jump_in_nested_finally) | 706 self.run_test(jump_in_nested_finally) |
| 707 def test_08_no_jump_too_far_forwards(self): | 707 def test_08_no_jump_too_far_forwards(self): |
| 708 self.run_test(no_jump_too_far_forwards) | 708 self.run_test(no_jump_too_far_forwards) |
| 709 def test_09_no_jump_too_far_backwards(self): | 709 def test_09_no_jump_too_far_backwards(self): |
| 710 self.run_test(no_jump_too_far_backwards) | 710 self.run_test(no_jump_too_far_backwards) |
| 711 def test_10_no_jump_to_except_1(self): | 711 def test_10_no_jump_to_except_1(self): |
| 712 self.run_test(no_jump_to_except_1) | 712 self.run_test(no_jump_to_except_1) |
| 713 def test_11_no_jump_to_except_2(self): | 713 def test_11_no_jump_to_except_2(self): |
| 714 self.run_test(no_jump_to_except_2) | 714 self.run_test(no_jump_to_except_2) |
| 715 def test_12_no_jump_to_except_3(self): | 715 def test_12_no_jump_to_except_3(self): |
| 716 self.run_test(no_jump_to_except_3) | 716 self.run_test(no_jump_to_except_3) |
| 717 def test_13_no_jump_to_except_4(self): | 717 def test_13_no_jump_to_except_4(self): |
| 718 self.run_test(no_jump_to_except_4) | 718 self.run_test(no_jump_to_except_4) |
| 719 def test_14_no_jump_forwards_into_block(self): | 719 def test_14_no_jump_forwards_into_block(self): |
| 720 self.run_test(no_jump_forwards_into_block) | 720 self.run_test(no_jump_forwards_into_block) |
| 721 def test_15_no_jump_backwards_into_block(self): | 721 def test_15_no_jump_backwards_into_block(self): |
| 722 self.run_test(no_jump_backwards_into_block) | 722 self.run_test(no_jump_backwards_into_block) |
| 723 def test_16_no_jump_into_finally_block(self): | 723 def test_16_no_jump_into_finally_block(self): |
| 724 self.run_test(no_jump_into_finally_block) | 724 self.run_test(no_jump_into_finally_block) |
| 725 def test_17_no_jump_out_of_finally_block(self): | 725 def test_17_no_jump_out_of_finally_block(self): |
| 726 self.run_test(no_jump_out_of_finally_block) | 726 self.run_test(no_jump_out_of_finally_block) |
| 727 def test_18_no_jump_to_non_integers(self): | 727 def test_18_no_jump_to_non_integers(self): |
| 728 self.run_test(no_jump_to_non_integers) | 728 self.run_test(no_jump_to_non_integers) |
| 729 def test_19_no_jump_without_trace_function(self): | 729 def test_19_no_jump_without_trace_function(self): |
| 730 no_jump_without_trace_function() | 730 no_jump_without_trace_function() |
| 731 | 731 |
| 732 def test_main(): | 732 def test_main(): |
| 733 test_support.run_unittest( | 733 test_support.run_unittest( |
| 734 TraceTestCase, | 734 TraceTestCase, |
| 735 RaisingTraceFuncTestCase, | 735 RaisingTraceFuncTestCase, |
| 736 JumpTestCase | 736 JumpTestCase |
| 737 ) | 737 ) |
| 738 | 738 |
| 739 if __name__ == "__main__": | 739 if __name__ == "__main__": |
| 740 test_main() | 740 test_main() |
| OLD | NEW |