Skip to content

Commit b39fd0c

Browse files
committed
Issue #11816: multiple improvements to the dis module
* get_instructions generator * ability to redirect output to a file * Bytecode and Instruction abstractions Patch by Nick Coghlan, Ryan Kelly and Thomas Kluyver.
1 parent 9d35133 commit b39fd0c

File tree

5 files changed

+747
-165
lines changed

5 files changed

+747
-165
lines changed

Diff for: Doc/library/dis.rst

+184-35
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ Example: Given the function :func:`myfunc`::
2626
def myfunc(alist):
2727
return len(alist)
2828

29-
the following command can be used to get the disassembly of :func:`myfunc`::
29+
the following command can be used to display the disassembly of
30+
:func:`myfunc`::
3031

3132
>>> dis.dis(myfunc)
3233
2 0 LOAD_GLOBAL 0 (len)
@@ -36,8 +37,62 @@ the following command can be used to get the disassembly of :func:`myfunc`::
3637

3738
(The "2" is a line number).
3839

39-
The :mod:`dis` module defines the following functions and constants:
40+
Bytecode analysis
41+
-----------------
4042

43+
The bytecode analysis API allows pieces of Python code to be wrapped in a
44+
:class:`Bytecode` object that provides easy access to details of the
45+
compiled code.
46+
47+
.. class:: Bytecode
48+
49+
The bytecode operations of a piece of code
50+
51+
This is a convenient wrapper around many of the functions listed below.
52+
Instantiate it with a function, method, string of code, or a code object
53+
(as returned by :func:`compile`).
54+
55+
Iterating over this yields the bytecode operations as :class:`Instruction`
56+
instances.
57+
58+
.. data:: codeobj
59+
60+
The compiled code object.
61+
62+
.. method:: display_code(*, file=None)
63+
64+
Print a formatted view of the bytecode operations, like :func:`dis`.
65+
66+
.. method:: info()
67+
68+
Return a formatted multi-line string with detailed information about the
69+
code object, like :func:`code_info`.
70+
71+
.. method:: show_info(*, file=None)
72+
73+
Print the information about the code object as returned by :meth:`info`.
74+
75+
.. versionadded:: 3.4
76+
77+
Example::
78+
79+
>>> bytecode = dis.Bytecode(myfunc)
80+
>>> for instr in bytecode:
81+
... print(instr.opname)
82+
...
83+
LOAD_GLOBAL
84+
LOAD_FAST
85+
CALL_FUNCTION
86+
RETURN_VALUE
87+
88+
89+
Analysis functions
90+
------------------
91+
92+
The :mod:`dis` module also defines the following analysis functions that
93+
convert the input directly to the desired output. They can be useful if
94+
only a single operation is being performed, so the intermediate analysis
95+
object isn't useful:
4196

4297
.. function:: code_info(x)
4398

@@ -51,17 +106,21 @@ The :mod:`dis` module defines the following functions and constants:
51106
.. versionadded:: 3.2
52107

53108

54-
.. function:: show_code(x)
109+
.. function:: show_code(x, *, file=None)
55110

56111
Print detailed code object information for the supplied function, method,
57112
source code string or code object to stdout.
58113

59-
This is a convenient shorthand for ``print(code_info(x))``, intended for
60-
interactive exploration at the interpreter prompt.
114+
This is a convenient shorthand for ``print(code_info(x), file=file)``,
115+
intended for interactive exploration at the interpreter prompt.
61116

62117
.. versionadded:: 3.2
63118

64-
.. function:: dis(x=None)
119+
.. versionchanged:: 3.4
120+
Added ``file`` parameter
121+
122+
123+
.. function:: dis(x=None, *, file=None)
65124

66125
Disassemble the *x* object. *x* can denote either a module, a class, a
67126
method, a function, a code object, a string of source code or a byte sequence
@@ -72,16 +131,28 @@ The :mod:`dis` module defines the following functions and constants:
72131
disassembled. If no object is provided, this function disassembles the last
73132
traceback.
74133

134+
The disassembly is written as text to the supplied ``file`` argument if
135+
provided and to ``sys.stdout`` otherwise.
136+
137+
.. versionchanged:: 3.4
138+
Added ``file`` parameter
75139

76-
.. function:: distb(tb=None)
140+
141+
.. function:: distb(tb=None, *, file=None)
77142

78143
Disassemble the top-of-stack function of a traceback, using the last
79144
traceback if none was passed. The instruction causing the exception is
80145
indicated.
81146

147+
The disassembly is written as text to the supplied ``file`` argument if
148+
provided and to ``sys.stdout`` otherwise.
149+
150+
.. versionchanged:: 3.4
151+
Added ``file`` parameter
82152

83-
.. function:: disassemble(code, lasti=-1)
84-
disco(code, lasti=-1)
153+
154+
.. function:: disassemble(code, lasti=-1, *, file=None)
155+
disco(code, lasti=-1, *, file=None)
85156
86157
Disassemble a code object, indicating the last instruction if *lasti* was
87158
provided. The output is divided in the following columns:
@@ -97,6 +168,26 @@ The :mod:`dis` module defines the following functions and constants:
97168
The parameter interpretation recognizes local and global variable names,
98169
constant values, branch targets, and compare operators.
99170

171+
The disassembly is written as text to the supplied ``file`` argument if
172+
provided and to ``sys.stdout`` otherwise.
173+
174+
.. versionchanged:: 3.4
175+
Added ``file`` parameter
176+
177+
178+
.. function:: get_instructions(x, *, line_offset=0)
179+
180+
Return an iterator over the instructions in the supplied function, method,
181+
source code string or code object.
182+
183+
The iterator generates a series of :class:`Instruction` named tuples
184+
giving the details of each operation in the supplied code.
185+
186+
The given *line_offset* is added to the ``starts_line`` attribute of any
187+
instructions that start a new line.
188+
189+
.. versionadded:: 3.4
190+
100191

101192
.. function:: findlinestarts(code)
102193

@@ -110,61 +201,60 @@ The :mod:`dis` module defines the following functions and constants:
110201
Detect all offsets in the code object *code* which are jump targets, and
111202
return a list of these offsets.
112203

204+
.. _bytecodes:
113205

114-
.. data:: opname
206+
Python Bytecode Instructions
207+
----------------------------
115208

116-
Sequence of operation names, indexable using the bytecode.
209+
The :func:`get_instructions` function and :class:`Bytecode` class provide
210+
details of bytecode instructions as :class:`Instruction` instances:
117211

212+
.. class:: Instruction
118213

119-
.. data:: opmap
214+
Details for a bytecode operation
120215

121-
Dictionary mapping operation names to bytecodes.
216+
.. data:: opcode
122217

218+
numeric code for operation, corresponding to the opcode values listed
219+
below and the bytecode values in the :ref:`opcode_collections`.
123220

124-
.. data:: cmp_op
125221

126-
Sequence of all compare operation names.
222+
.. data:: opname
127223

224+
human readable name for operation
128225

129-
.. data:: hasconst
130226

131-
Sequence of bytecodes that have a constant parameter.
227+
.. data:: arg
132228

229+
numeric argument to operation (if any), otherwise None
133230

134-
.. data:: hasfree
135231

136-
Sequence of bytecodes that access a free variable.
232+
.. data:: argval
137233

234+
resolved arg value (if known), otherwise same as arg
138235

139-
.. data:: hasname
140236

141-
Sequence of bytecodes that access an attribute by name.
237+
.. data:: argrepr
142238

239+
human readable description of operation argument
143240

144-
.. data:: hasjrel
145241

146-
Sequence of bytecodes that have a relative jump target.
242+
.. data:: offset
147243

244+
start index of operation within bytecode sequence
148245

149-
.. data:: hasjabs
150246

151-
Sequence of bytecodes that have an absolute jump target.
152-
153-
154-
.. data:: haslocal
155-
156-
Sequence of bytecodes that access a local variable.
247+
.. data:: starts_line
157248

249+
line started by this opcode (if any), otherwise None
158250

159-
.. data:: hascompare
160251

161-
Sequence of bytecodes of Boolean operations.
252+
.. data:: is_jump_target
162253

254+
True if other code jumps to here, otherwise False
163255

164-
.. _bytecodes:
256+
.. versionadded:: 3.4
165257

166-
Python Bytecode Instructions
167-
----------------------------
168258

169259
The Python compiler currently generates the following bytecode instructions.
170260

@@ -820,3 +910,62 @@ the more significant byte last.
820910
which don't take arguments ``< HAVE_ARGUMENT`` and those which do ``>=
821911
HAVE_ARGUMENT``.
822912

913+
.. _opcode_collections:
914+
915+
Opcode collections
916+
------------------
917+
918+
These collections are provided for automatic introspection of bytecode
919+
instructions:
920+
921+
.. data:: opname
922+
923+
Sequence of operation names, indexable using the bytecode.
924+
925+
926+
.. data:: opmap
927+
928+
Dictionary mapping operation names to bytecodes.
929+
930+
931+
.. data:: cmp_op
932+
933+
Sequence of all compare operation names.
934+
935+
936+
.. data:: hasconst
937+
938+
Sequence of bytecodes that have a constant parameter.
939+
940+
941+
.. data:: hasfree
942+
943+
Sequence of bytecodes that access a free variable (note that 'free' in
944+
this context refers to names in the current scope that are referenced by
945+
inner scopes or names in outer scopes that are referenced from this scope.
946+
It does *not* include references to global or builtin scopes).
947+
948+
949+
.. data:: hasname
950+
951+
Sequence of bytecodes that access an attribute by name.
952+
953+
954+
.. data:: hasjrel
955+
956+
Sequence of bytecodes that have a relative jump target.
957+
958+
959+
.. data:: hasjabs
960+
961+
Sequence of bytecodes that have an absolute jump target.
962+
963+
964+
.. data:: haslocal
965+
966+
Sequence of bytecodes that access a local variable.
967+
968+
969+
.. data:: hascompare
970+
971+
Sequence of bytecodes of Boolean operations.

Diff for: Doc/whatsnew/3.4.rst

+15
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,21 @@ Improved Modules
152152
================
153153

154154

155+
dis
156+
---
157+
158+
The :mod:`dis` module is now built around an :class:`Instruction` class that
159+
provides details of individual bytecode operations and a
160+
:func:`get_instructions` iterator that emits the Instruction stream for a
161+
given piece of Python code. The various display tools in the :mod:`dis`
162+
module have been updated to be based on these new components.
163+
164+
The new :class:`dis.Bytecode` class provides an object-oriented API for
165+
inspecting bytecode, both in human-readable form and for iterating over
166+
instructions.
167+
168+
(Contributed by Nick Coghlan, Ryan Kelly and Thomas Kluyver in :issue:`11816`)
169+
155170
doctest
156171
-------
157172

0 commit comments

Comments
 (0)