diff options
author | Michael W. Hudson <mwh@python.net> | 2002-08-30 13:09:51 (GMT) |
---|---|---|
committer | Michael W. Hudson <mwh@python.net> | 2002-08-30 13:09:51 (GMT) |
commit | 53d58bb369fbbc1ae93ca423f30b3beb2d83a9a1 (patch) | |
tree | d2cfada7ddfa673a343155bfbad7de1166ea3790 /Lib | |
parent | b05e056e9f17f68daf106e1b018d1bbab2943148 (diff) | |
download | cpython-53d58bb369fbbc1ae93ca423f30b3beb2d83a9a1.zip cpython-53d58bb369fbbc1ae93ca423f30b3beb2d83a9a1.tar.gz cpython-53d58bb369fbbc1ae93ca423f30b3beb2d83a9a1.tar.bz2 |
Further SET_LINENO reomval fixes. See comments in patch #587933.
Use a slightly different strategy to determine when not to call the line
trace function. This removes the need for the RETURN_NONE opcode, so
that's gone again. Update docs and comments to match.
Thanks to Neal and Armin!
Also add a test suite. This should have come with the original patch...
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/dis.py | 1 | ||||
-rw-r--r-- | Lib/test/test_trace.py | 110 |
2 files changed, 110 insertions, 1 deletions
@@ -254,7 +254,6 @@ def_op('INPLACE_XOR', 78) def_op('INPLACE_OR', 79) def_op('BREAK_LOOP', 80) -def_op('RETURN_NONE', 81) def_op('LOAD_LOCALS', 82) def_op('RETURN_VALUE', 83) def_op('IMPORT_STAR', 84) diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py new file mode 100644 index 0000000..ee847b6 --- /dev/null +++ b/Lib/test/test_trace.py @@ -0,0 +1,110 @@ +# Testing the line trace facility. + +from test import test_support +import unittest +import sys +import difflib + +# A very basic example. If this fails, we're in deep trouble. +def basic(): + return 1 + +basic.events = [(0, 'call'), + (1, 'line'), + (1, 'return')] + +# Armin Rigo's failing example: +def arigo_example(): + x = 1 + del x + while 0: + pass + x = 1 + +arigo_example.events = [(0, 'call'), + (1, 'line'), + (2, 'line'), + (3, 'line'), + (5, 'line'), + (5, 'return')] + +# check that lines consisting of just one instruction get traced: +def one_instr_line(): + x = 1 + del x + x = 1 + +one_instr_line.events = [(0, 'call'), + (1, 'line'), + (2, 'line'), + (3, 'line'), + (3, 'return')] + +def no_pop_tops(): # 0 + x = 1 # 1 + for a in range(2): # 2 + if a: # 3 + x = 1 # 4 + else: # 5 + x = 1 # 6 + +no_pop_tops.events = [(0, 'call'), + (1, 'line'), + (2, 'line'), + (3, 'line'), + (6, 'line'), + (2, 'line'), + (3, 'line'), + (4, 'line'), + (2, 'line'), + (6, 'return')] + +def no_pop_blocks(): + while 0: + bla + x = 1 + +no_pop_blocks.events = [(0, 'call'), + (1, 'line'), + (3, 'line'), + (3, 'return')] + +class Tracer: + def __init__(self): + self.events = [] + def trace(self, frame, event, arg): + self.events.append((frame.f_lineno, event)) + return self.trace + +class TraceTestCase(unittest.TestCase): + def run_test(self, func): + tracer = Tracer() + sys.settrace(tracer.trace) + func() + sys.settrace(None) + fl = func.func_code.co_firstlineno + events = [(l - fl, e) for (l, e) in tracer.events] + if events != func.events: + self.fail( + "events did not match expectation:\n" + + "\n".join(difflib.ndiff(map(str, func.events), + map(str, events)))) + + def test_1_basic(self): + self.run_test(basic) + def test_2_arigo(self): + self.run_test(arigo_example) + def test_3_one_instr(self): + self.run_test(one_instr_line) + def test_4_no_pop_blocks(self): + self.run_test(no_pop_blocks) + def test_5_no_pop_tops(self): + self.run_test(no_pop_tops) + + + +def test_main(): + test_support.run_unittest(TraceTestCase) + +if __name__ == "__main__": + test_main() |