summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2020-11-12 09:43:29 (GMT)
committerGitHub <noreply@github.com>2020-11-12 09:43:29 (GMT)
commit877df851c3ecdb55306840e247596e7b7805a60a (patch)
treeec00c0af84f9f228d78e23e8c8b38201129f8fae /Lib
parentcda99b4022daa08ac74b0420e9903cce883d91c6 (diff)
downloadcpython-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.py33
-rw-r--r--Lib/test/test_code.py2
-rw-r--r--Lib/test/test_compile.py4
-rw-r--r--Lib/test/test_opcodes.py2
-rw-r--r--Lib/test/test_pdb.py3
-rw-r--r--Lib/test/test_sys_settrace.py18
6 files changed, 28 insertions, 34 deletions
diff --git a/Lib/dis.py b/Lib/dis.py
index e289e17..ea50f56 100644
--- a/Lib/dis.py
+++ b/Lib/dis.py
@@ -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)