bpo-45168: change dis output to omit missing values rather than replacing them by their index (GH-28313)

This commit is contained in:
Irit Katriel 2021-09-14 10:09:05 +01:00 committed by GitHub
parent c2f1e95337
commit c99fc4e53a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 19 deletions

View File

@ -293,12 +293,13 @@ details of bytecode instructions as :class:`Instruction` instances:
.. data:: argval .. data:: argval
resolved arg value (if known), otherwise same as arg resolved arg value (if any), otherwise ``None``
.. data:: argrepr .. data:: argrepr
human readable description of operation argument human readable description of operation argument (if any),
otherwise an empty string.
.. data:: offset .. data:: offset

View File

@ -125,6 +125,13 @@ def pretty_flags(flags):
names.append(hex(flags)) names.append(hex(flags))
return ", ".join(names) return ", ".join(names)
class _Unknown:
def __repr__(self):
return "<unknown>"
# Sentinel to represent values that cannot be calculated
UNKNOWN = _Unknown()
def _get_code_object(x): def _get_code_object(x):
"""Helper to handle methods, compiled or raw code objects, and strings.""" """Helper to handle methods, compiled or raw code objects, and strings."""
# Extract functions from methods. # Extract functions from methods.
@ -315,28 +322,28 @@ def _get_const_info(const_index, const_list):
Returns the dereferenced constant and its repr if the constant Returns the dereferenced constant and its repr if the constant
list is defined. list is defined.
Otherwise returns the constant index and its repr(). Otherwise returns the sentinel value dis.UNKNOWN for the value
and an empty string for its repr.
""" """
argval = const_index
if const_list is not None: if const_list is not None:
argval = const_list[const_index] argval = const_list[const_index]
return argval, repr(argval) return argval, repr(argval)
else:
return UNKNOWN, ''
def _get_name_info(name_index, get_name, **extrainfo): def _get_name_info(name_index, get_name, **extrainfo):
"""Helper to get optional details about named references """Helper to get optional details about named references
Returns the dereferenced name as both value and repr if the name Returns the dereferenced name as both value and repr if the name
list is defined. list is defined.
Otherwise returns the name index and its repr(). Otherwise returns the sentinel value dis.UNKNOWN for the value
and an empty string for its repr.
""" """
argval = name_index
if get_name is not None: if get_name is not None:
argval = get_name(name_index, **extrainfo) argval = get_name(name_index, **extrainfo)
argrepr = argval return argval, argval
else: else:
argrepr = repr(argval) return UNKNOWN, ''
return argval, argrepr
def parse_varint(iterator): def parse_varint(iterator):
b = next(iterator) b = next(iterator)

View File

@ -48,12 +48,12 @@ dis_c_instance_method = """\
""" % (_C.__init__.__code__.co_firstlineno + 1,) """ % (_C.__init__.__code__.co_firstlineno + 1,)
dis_c_instance_method_bytes = """\ dis_c_instance_method_bytes = """\
0 LOAD_FAST 1 (1) 0 LOAD_FAST 1
2 LOAD_CONST 1 (1) 2 LOAD_CONST 1
4 COMPARE_OP 2 (==) 4 COMPARE_OP 2 (==)
6 LOAD_FAST 0 (0) 6 LOAD_FAST 0
8 STORE_ATTR 0 (0) 8 STORE_ATTR 0
10 LOAD_CONST 0 (0) 10 LOAD_CONST 0
12 RETURN_VALUE 12 RETURN_VALUE
""" """
@ -105,11 +105,11 @@ dis_f = """\
dis_f_co_code = """\ dis_f_co_code = """\
0 LOAD_GLOBAL 0 (0) 0 LOAD_GLOBAL 0
2 LOAD_FAST 0 (0) 2 LOAD_FAST 0
4 CALL_FUNCTION 1 4 CALL_FUNCTION 1
6 POP_TOP 6 POP_TOP
8 LOAD_CONST 1 (1) 8 LOAD_CONST 1
10 RETURN_VALUE 10 RETURN_VALUE
""" """

View File

@ -0,0 +1 @@
Change :func:`dis.dis` output to omit op arg values that cannot be resolved due to ``co_consts``, ``co_names`` etc not being provided. Previously the oparg itself was repeated in the value field, which is not useful and can be confusing.