diff options
author | Mark Shannon <mark@hotpy.org> | 2020-11-12 09:43:29 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-12 09:43:29 (GMT) |
commit | 877df851c3ecdb55306840e247596e7b7805a60a (patch) | |
tree | ec00c0af84f9f228d78e23e8c8b38201129f8fae /Lib | |
parent | cda99b4022daa08ac74b0420e9903cce883d91c6 (diff) | |
download | cpython-877df851c3ecdb55306840e247596e7b7805a60a.zip cpython-877df851c3ecdb55306840e247596e7b7805a60a.tar.gz cpython-877df851c3ecdb55306840e247596e7b7805a60a.tar.bz2 |
bpo-42246: Partial implementation of PEP 626. (GH-23113)
* Implement new line number table format, as defined in PEP 626.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/dis.py | 33 | ||||
-rw-r--r-- | Lib/test/test_code.py | 2 | ||||
-rw-r--r-- | Lib/test/test_compile.py | 4 | ||||
-rw-r--r-- | Lib/test/test_opcodes.py | 2 | ||||
-rw-r--r-- | Lib/test/test_pdb.py | 3 | ||||
-rw-r--r-- | Lib/test/test_sys_settrace.py | 18 |
6 files changed, 28 insertions, 34 deletions
@@ -449,32 +449,15 @@ def findlabels(code): def findlinestarts(code): """Find the offsets in a byte code which are start of lines in the source. - Generate pairs (offset, lineno) as described in Python/compile.c. - + Generate pairs (offset, lineno) """ - byte_increments = code.co_lnotab[0::2] - line_increments = code.co_lnotab[1::2] - bytecode_len = len(code.co_code) - - lastlineno = None - lineno = code.co_firstlineno - addr = 0 - for byte_incr, line_incr in zip(byte_increments, line_increments): - if byte_incr: - if lineno != lastlineno: - yield (addr, lineno) - lastlineno = lineno - addr += byte_incr - if addr >= bytecode_len: - # The rest of the lnotab byte offsets are past the end of - # the bytecode, so the lines were optimized away. - return - if line_incr >= 0x80: - # line_increments is an array of 8-bit signed integers - line_incr -= 0x100 - lineno += line_incr - if lineno != lastlineno: - yield (addr, lineno) + lastline = None + for start, end, line in code.co_lines(): + if line is not None and line != lastline: + lastline = line + yield start, line + return + class Bytecode: """The bytecode operations of a piece of code diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index ac3dde7..467e8e5 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -258,7 +258,7 @@ class CodeTest(unittest.TestCase): ("co_cellvars", ("cellvar",)), ("co_filename", "newfilename"), ("co_name", "newname"), - ("co_lnotab", code2.co_lnotab), + ("co_linetable", code2.co_linetable), ): with self.subTest(attr=attr, value=value): new_code = code.replace(**{attr: value}) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 6055192..0e06d11 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -155,8 +155,8 @@ if 1: def test_leading_newlines(self): s256 = "".join(["\n"] * 256 + ["spam"]) co = compile(s256, 'fn', 'exec') - self.assertEqual(co.co_firstlineno, 257) - self.assertEqual(co.co_lnotab, bytes()) + self.assertEqual(co.co_firstlineno, 1) + self.assertEqual(list(co.co_lines()), [(0, 4, 257), (4, 8, None)]) def test_literals_with_leading_zeroes(self): for arg in ["077787", "0xj", "0x.", "0e", "090000000000000", diff --git a/Lib/test/test_opcodes.py b/Lib/test/test_opcodes.py index 1152eb6..e510364 100644 --- a/Lib/test/test_opcodes.py +++ b/Lib/test/test_opcodes.py @@ -27,7 +27,7 @@ class OpcodeTest(unittest.TestCase): with open(ann_module.__file__) as f: txt = f.read() co = compile(txt, ann_module.__file__, 'exec') - self.assertEqual(co.co_firstlineno, 3) + self.assertEqual(co.co_firstlineno, 1) except OSError: pass diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index e564513..4bb574f 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -1645,9 +1645,10 @@ def bœr(): 'debug doesnotexist', 'c', ]) - stdout, _ = self.run_pdb_script('', commands + '\n') + stdout, _ = self.run_pdb_script('pass', commands + '\n') self.assertEqual(stdout.splitlines()[1:], [ + '-> pass', '(Pdb) *** SyntaxError: unexpected EOF while parsing', '(Pdb) ENTERING RECURSIVE DEBUGGER', diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index dd4418d..66b1b36 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -220,8 +220,7 @@ ireturn_example.events = [(0, 'call'), (2, 'line'), (3, 'line'), (4, 'line'), - (6, 'line'), - (6, 'return')] + (4, 'return')] # Tight loop with while(1) example (SF #765624) def tightloop_example(): @@ -602,6 +601,17 @@ class TraceTestCase(unittest.TestCase): self.compare_events(doit_async.__code__.co_firstlineno, tracer.events, events) + def test_21_repeated_pass(self): + def func(): + pass + pass + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (2, 'return')]) + def test_loop_in_try_except(self): # https://bugs.python.org/issue41670 @@ -766,7 +776,7 @@ class JumpTracer: if (self.firstLine is None and frame.f_code == self.code and event == 'line'): self.firstLine = frame.f_lineno - 1 - if (event == self.event and self.firstLine and + if (event == self.event and self.firstLine is not None and frame.f_lineno == self.firstLine + self.jumpFrom): f = frame while f is not None and f.f_code != self.code: @@ -1540,7 +1550,7 @@ output.append(4) """, "<fake module>", "exec") class fake_function: __code__ = code - tracer = JumpTracer(fake_function, 2, 0) + tracer = JumpTracer(fake_function, 4, 1) sys.settrace(tracer.trace) namespace = {"output": []} exec(code, namespace) |