From 751bacf740e0ef9911dbbd991bffcf1e72d6216b Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Thu, 14 Jul 2022 10:08:07 -0400 Subject: [PATCH] gh-94816: Improve coverage of decode_linetable This makes calls to co_lnotab to exercise this code, as well as generating synthetically large code to exercise the corner cases where line numbers need multiple bytes. --- Lib/test/test_code.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index fd68f6dee7915a..c3ce933d4f655d 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -17,6 +17,7 @@ freevars: () nlocals: 2 flags: 3 +lnotab: b'\\x04\\x01\\n\\x02' consts: ('None', '') >>> dump(f(4).__code__) @@ -30,6 +31,7 @@ freevars: ('x',) nlocals: 1 flags: 19 +lnotab: b'\\x04\\x01' consts: ('None',) >>> def h(x, y): @@ -50,6 +52,7 @@ freevars: () nlocals: 5 flags: 3 +lnotab: b'\\x02\\x01\\n\\x01\\n\\x01\\n\\x01' consts: ('None',) >>> def attrs(obj): @@ -68,6 +71,7 @@ freevars: () nlocals: 1 flags: 3 +lnotab: b'\\x02\\x01.\\x01.\\x01' consts: ('None',) >>> def optimize_away(): @@ -87,6 +91,7 @@ freevars: () nlocals: 0 flags: 3 +lnotab: b'\\x02\\x02\\x02\\x01\\x02\\x01' consts: ("'doc string'", 'None') >>> def keywordonly_args(a,b,*,k1): @@ -104,6 +109,7 @@ freevars: () nlocals: 3 flags: 3 +lnotab: b'\\x02\\x01' consts: ('None',) >>> def posonly_args(a,b,/,c): @@ -121,6 +127,7 @@ freevars: () nlocals: 3 flags: 3 +lnotab: b'\\x02\\x01' consts: ('None',) """ @@ -159,7 +166,8 @@ def dump(co): """Print out a text representation of a code object.""" for attr in ["name", "argcount", "posonlyargcount", "kwonlyargcount", "names", "varnames", - "cellvars", "freevars", "nlocals", "flags"]: + "cellvars", "freevars", "nlocals", "flags", + "lnotab"]: print("%s: %s" % (attr, getattr(co, "co_" + attr))) print("consts:", tuple(consts(co.co_consts))) @@ -428,6 +436,21 @@ def func(): self.assertIsNone(line) self.assertEqual(end_line, new_code.co_firstlineno + 1) + def test_large_lnotab(self): + d = {} + lines = ( + ["def f():"] + + [' """'] + + [' .'] * (1 << 17) + + [' """'] + + [" x = 1"] * (1 << 17) + ) + source = "\n".join(lines) + exec(source, d) + code = d["f"].__code__ + + self.assertEqual(len(code.co_lnotab), 264208) + def isinterned(s): return s is sys.intern(('_' + s + '_')[1:-1])