summaryrefslogtreecommitdiff
path: root/Lib/dis.py
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2017-04-19 20:36:31 +0300
committerGitHub <noreply@github.com>2017-04-19 20:36:31 +0300
commitd90045f319e2ea9772b9fbd62a05fdf34af96b6c (patch)
treec00114d2e77720639c3c7523056a2f7e1a854537 /Lib/dis.py
parentbf623ae8843dc30b28c574bec8d29fc14be59d86 (diff)
downloadcpython-git-d90045f319e2ea9772b9fbd62a05fdf34af96b6c.tar.gz
bpo-22352: Adjust widths in the output of dis.dis() for large line numbers and (#1153)
instruction offsets. Add tests for widths of opcode names.
Diffstat (limited to 'Lib/dis.py')
-rw-r--r--Lib/dis.py30
1 files changed, 23 insertions, 7 deletions
diff --git a/Lib/dis.py b/Lib/dis.py
index f93d5b22d4..f3c18a5fde 100644
--- a/Lib/dis.py
+++ b/Lib/dis.py
@@ -175,6 +175,9 @@ _Instruction.offset.__doc__ = "Start index of operation within bytecode sequence
_Instruction.starts_line.__doc__ = "Line started by this opcode (if any), otherwise None"
_Instruction.is_jump_target.__doc__ = "True if other code jumps to here, otherwise False"
+_OPNAME_WIDTH = 20
+_OPARG_WIDTH = 5
+
class Instruction(_Instruction):
"""Details for a bytecode operation
@@ -189,11 +192,12 @@ class Instruction(_Instruction):
is_jump_target - True if other code jumps to here, otherwise False
"""
- def _disassemble(self, lineno_width=3, mark_as_current=False):
+ def _disassemble(self, lineno_width=3, mark_as_current=False, offset_width=4):
"""Format instruction details for inclusion in disassembly output
*lineno_width* sets the width of the line number field (0 omits it)
*mark_as_current* inserts a '-->' marker arrow as part of the line
+ *offset_width* sets the width of the instruction offset field
"""
fields = []
# Column: Source code line number
@@ -214,12 +218,12 @@ class Instruction(_Instruction):
else:
fields.append(' ')
# Column: Instruction offset from start of code sequence
- fields.append(repr(self.offset).rjust(4))
+ fields.append(repr(self.offset).rjust(offset_width))
# Column: Opcode name
- fields.append(self.opname.ljust(20))
+ fields.append(self.opname.ljust(_OPNAME_WIDTH))
# Column: Opcode argument
if self.arg is not None:
- fields.append(repr(self.arg).rjust(5))
+ fields.append(repr(self.arg).rjust(_OPARG_WIDTH))
# Column: Opcode argument details
if self.argrepr:
fields.append('(' + self.argrepr + ')')
@@ -339,8 +343,19 @@ def _disassemble_bytes(code, lasti=-1, varnames=None, names=None,
*, file=None, line_offset=0):
# Omit the line number column entirely if we have no line number info
show_lineno = linestarts is not None
- # TODO?: Adjust width upwards if max(linestarts.values()) >= 1000?
- lineno_width = 3 if show_lineno else 0
+ if show_lineno:
+ maxlineno = max(linestarts.values()) + line_offset
+ if maxlineno >= 1000:
+ lineno_width = len(str(maxlineno))
+ else:
+ lineno_width = 3
+ else:
+ lineno_width = 0
+ maxoffset = len(code) - 2
+ if maxoffset >= 10000:
+ offset_width = len(str(maxoffset))
+ else:
+ offset_width = 4
for instr in _get_instructions_bytes(code, varnames, names,
constants, cells, linestarts,
line_offset=line_offset):
@@ -350,7 +365,8 @@ def _disassemble_bytes(code, lasti=-1, varnames=None, names=None,
if new_source_line:
print(file=file)
is_current_instr = instr.offset == lasti
- print(instr._disassemble(lineno_width, is_current_instr), file=file)
+ print(instr._disassemble(lineno_width, is_current_instr, offset_width),
+ file=file)
def _disassemble_str(source, *, file=None):
"""Compile the source string, then disassemble the code object."""