summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2020-12-21 07:35:21 -0500
committerNed Batchelder <ned@nedbatchelder.com>2021-01-10 09:46:18 -0500
commit840537a7dc0cbaaea5b65ee02a463d559afa20bc (patch)
treef2801fd6952ce5653e1b1e2ec4d10754a44ac7a2
parent71053d9757bc0299e4825df62d54ae2799c5f139 (diff)
downloadpython-coveragepy-git-840537a7dc0cbaaea5b65ee02a463d559afa20bc.tar.gz
show_pyc: Interpret co_lnotab, and show co_lines()
-rw-r--r--lab/show_pyc.py36
1 files changed, 36 insertions, 0 deletions
diff --git a/lab/show_pyc.py b/lab/show_pyc.py
index d0ed8224..2e21eb64 100644
--- a/lab/show_pyc.py
+++ b/lab/show_pyc.py
@@ -114,6 +114,14 @@ def show_code(code, indent='', number=None):
print("%sfilename %r" % (indent, code.co_filename))
print("%sfirstlineno %d" % (indent, code.co_firstlineno))
show_hex("lnotab", code.co_lnotab, indent=indent)
+ print(" %s%s" % (indent, ", ".join("%r:%r" % (line, byte) for byte, line in lnotab_interpreted(code))))
+ if hasattr(code, "co_linetable"):
+ show_hex("linetable", code.co_linetable, indent=indent)
+ if hasattr(code, "co_lines"):
+ print(" %sco_lines %s" % (
+ indent,
+ ", ".join("%r:%r-%r" % (line, start, end) for start, end, line in code.co_lines())
+ ))
def show_hex(label, h, indent):
h = binascii.hexlify(h)
@@ -124,6 +132,34 @@ def show_hex(label, h, indent):
for i in range(0, len(h), 60):
print("%s %s" % (indent, h[i:i+60].decode('ascii')))
+if sys.version_info >= (3,):
+ def bytes_to_ints(bytes_value):
+ return bytes_value
+else:
+ def bytes_to_ints(bytes_value):
+ for byte in bytes_value:
+ yield ord(byte)
+
+def lnotab_interpreted(code):
+ # Adapted from dis.py in the standard library.
+ byte_increments = bytes_to_ints(code.co_lnotab[0::2])
+ line_increments = bytes_to_ints(code.co_lnotab[1::2])
+
+ last_line_num = None
+ line_num = code.co_firstlineno
+ byte_num = 0
+ for byte_incr, line_incr in zip(byte_increments, line_increments):
+ if byte_incr:
+ if line_num != last_line_num:
+ yield (byte_num, line_num)
+ last_line_num = line_num
+ byte_num += byte_incr
+ if sys.version_info >= (3, 6) and line_incr >= 0x80:
+ line_incr -= 0x100
+ line_num += line_incr
+ if line_num != last_line_num:
+ yield (byte_num, line_num)
+
def flag_words(flags, flag_defs):
words = []
for word, flag in flag_defs: