Kaydet (Commit) b39fd0c9 authored tarafından Nick Coghlan's avatar Nick Coghlan

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.
üst 9d351332
...@@ -26,7 +26,8 @@ Example: Given the function :func:`myfunc`:: ...@@ -26,7 +26,8 @@ Example: Given the function :func:`myfunc`::
def myfunc(alist): def myfunc(alist):
return len(alist) return len(alist)
the following command can be used to get the disassembly of :func:`myfunc`:: the following command can be used to display the disassembly of
:func:`myfunc`::
>>> dis.dis(myfunc) >>> dis.dis(myfunc)
2 0 LOAD_GLOBAL 0 (len) 2 0 LOAD_GLOBAL 0 (len)
...@@ -36,8 +37,62 @@ the following command can be used to get the disassembly of :func:`myfunc`:: ...@@ -36,8 +37,62 @@ the following command can be used to get the disassembly of :func:`myfunc`::
(The "2" is a line number). (The "2" is a line number).
The :mod:`dis` module defines the following functions and constants: Bytecode analysis
-----------------
The bytecode analysis API allows pieces of Python code to be wrapped in a
:class:`Bytecode` object that provides easy access to details of the
compiled code.
.. class:: Bytecode
The bytecode operations of a piece of code
This is a convenient wrapper around many of the functions listed below.
Instantiate it with a function, method, string of code, or a code object
(as returned by :func:`compile`).
Iterating over this yields the bytecode operations as :class:`Instruction`
instances.
.. data:: codeobj
The compiled code object.
.. method:: display_code(*, file=None)
Print a formatted view of the bytecode operations, like :func:`dis`.
.. method:: info()
Return a formatted multi-line string with detailed information about the
code object, like :func:`code_info`.
.. method:: show_info(*, file=None)
Print the information about the code object as returned by :meth:`info`.
.. versionadded:: 3.4
Example::
>>> bytecode = dis.Bytecode(myfunc)
>>> for instr in bytecode:
... print(instr.opname)
...
LOAD_GLOBAL
LOAD_FAST
CALL_FUNCTION
RETURN_VALUE
Analysis functions
------------------
The :mod:`dis` module also defines the following analysis functions that
convert the input directly to the desired output. They can be useful if
only a single operation is being performed, so the intermediate analysis
object isn't useful:
.. function:: code_info(x) .. function:: code_info(x)
...@@ -51,17 +106,21 @@ The :mod:`dis` module defines the following functions and constants: ...@@ -51,17 +106,21 @@ The :mod:`dis` module defines the following functions and constants:
.. versionadded:: 3.2 .. versionadded:: 3.2
.. function:: show_code(x) .. function:: show_code(x, *, file=None)
Print detailed code object information for the supplied function, method, Print detailed code object information for the supplied function, method,
source code string or code object to stdout. source code string or code object to stdout.
This is a convenient shorthand for ``print(code_info(x))``, intended for This is a convenient shorthand for ``print(code_info(x), file=file)``,
interactive exploration at the interpreter prompt. intended for interactive exploration at the interpreter prompt.
.. versionadded:: 3.2 .. versionadded:: 3.2
.. function:: dis(x=None) .. versionchanged:: 3.4
Added ``file`` parameter
.. function:: dis(x=None, *, file=None)
Disassemble the *x* object. *x* can denote either a module, a class, a Disassemble the *x* object. *x* can denote either a module, a class, a
method, a function, a code object, a string of source code or a byte sequence 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: ...@@ -72,16 +131,28 @@ The :mod:`dis` module defines the following functions and constants:
disassembled. If no object is provided, this function disassembles the last disassembled. If no object is provided, this function disassembles the last
traceback. traceback.
The disassembly is written as text to the supplied ``file`` argument if
provided and to ``sys.stdout`` otherwise.
.. versionchanged:: 3.4
Added ``file`` parameter
.. function:: distb(tb=None)
.. function:: distb(tb=None, *, file=None)
Disassemble the top-of-stack function of a traceback, using the last Disassemble the top-of-stack function of a traceback, using the last
traceback if none was passed. The instruction causing the exception is traceback if none was passed. The instruction causing the exception is
indicated. indicated.
The disassembly is written as text to the supplied ``file`` argument if
provided and to ``sys.stdout`` otherwise.
.. versionchanged:: 3.4
Added ``file`` parameter
.. function:: disassemble(code, lasti=-1)
disco(code, lasti=-1) .. function:: disassemble(code, lasti=-1, *, file=None)
disco(code, lasti=-1, *, file=None)
Disassemble a code object, indicating the last instruction if *lasti* was Disassemble a code object, indicating the last instruction if *lasti* was
provided. The output is divided in the following columns: provided. The output is divided in the following columns:
...@@ -97,6 +168,26 @@ The :mod:`dis` module defines the following functions and constants: ...@@ -97,6 +168,26 @@ The :mod:`dis` module defines the following functions and constants:
The parameter interpretation recognizes local and global variable names, The parameter interpretation recognizes local and global variable names,
constant values, branch targets, and compare operators. constant values, branch targets, and compare operators.
The disassembly is written as text to the supplied ``file`` argument if
provided and to ``sys.stdout`` otherwise.
.. versionchanged:: 3.4
Added ``file`` parameter
.. function:: get_instructions(x, *, line_offset=0)
Return an iterator over the instructions in the supplied function, method,
source code string or code object.
The iterator generates a series of :class:`Instruction` named tuples
giving the details of each operation in the supplied code.
The given *line_offset* is added to the ``starts_line`` attribute of any
instructions that start a new line.
.. versionadded:: 3.4
.. function:: findlinestarts(code) .. function:: findlinestarts(code)
...@@ -110,61 +201,60 @@ The :mod:`dis` module defines the following functions and constants: ...@@ -110,61 +201,60 @@ The :mod:`dis` module defines the following functions and constants:
Detect all offsets in the code object *code* which are jump targets, and Detect all offsets in the code object *code* which are jump targets, and
return a list of these offsets. return a list of these offsets.
.. _bytecodes:
.. data:: opname Python Bytecode Instructions
----------------------------
Sequence of operation names, indexable using the bytecode. The :func:`get_instructions` function and :class:`Bytecode` class provide
details of bytecode instructions as :class:`Instruction` instances:
.. class:: Instruction
.. data:: opmap Details for a bytecode operation
Dictionary mapping operation names to bytecodes. .. data:: opcode
numeric code for operation, corresponding to the opcode values listed
below and the bytecode values in the :ref:`opcode_collections`.
.. data:: cmp_op
Sequence of all compare operation names. .. data:: opname
human readable name for operation
.. data:: hasconst
Sequence of bytecodes that have a constant parameter. .. data:: arg
numeric argument to operation (if any), otherwise None
.. data:: hasfree
Sequence of bytecodes that access a free variable. .. data:: argval
resolved arg value (if known), otherwise same as arg
.. data:: hasname
Sequence of bytecodes that access an attribute by name. .. data:: argrepr
human readable description of operation argument
.. data:: hasjrel
Sequence of bytecodes that have a relative jump target. .. data:: offset
start index of operation within bytecode sequence
.. data:: hasjabs
Sequence of bytecodes that have an absolute jump target. .. data:: starts_line
.. data:: haslocal
Sequence of bytecodes that access a local variable.
line started by this opcode (if any), otherwise None
.. data:: hascompare
Sequence of bytecodes of Boolean operations. .. data:: is_jump_target
True if other code jumps to here, otherwise False
.. _bytecodes: .. versionadded:: 3.4
Python Bytecode Instructions
----------------------------
The Python compiler currently generates the following bytecode instructions. The Python compiler currently generates the following bytecode instructions.
...@@ -820,3 +910,62 @@ the more significant byte last. ...@@ -820,3 +910,62 @@ the more significant byte last.
which don't take arguments ``< HAVE_ARGUMENT`` and those which do ``>= which don't take arguments ``< HAVE_ARGUMENT`` and those which do ``>=
HAVE_ARGUMENT``. HAVE_ARGUMENT``.
.. _opcode_collections:
Opcode collections
------------------
These collections are provided for automatic introspection of bytecode
instructions:
.. data:: opname
Sequence of operation names, indexable using the bytecode.
.. data:: opmap
Dictionary mapping operation names to bytecodes.
.. data:: cmp_op
Sequence of all compare operation names.
.. data:: hasconst
Sequence of bytecodes that have a constant parameter.
.. data:: hasfree
Sequence of bytecodes that access a free variable (note that 'free' in
this context refers to names in the current scope that are referenced by
inner scopes or names in outer scopes that are referenced from this scope.
It does *not* include references to global or builtin scopes).
.. data:: hasname
Sequence of bytecodes that access an attribute by name.
.. data:: hasjrel
Sequence of bytecodes that have a relative jump target.
.. data:: hasjabs
Sequence of bytecodes that have an absolute jump target.
.. data:: haslocal
Sequence of bytecodes that access a local variable.
.. data:: hascompare
Sequence of bytecodes of Boolean operations.
...@@ -152,6 +152,21 @@ Improved Modules ...@@ -152,6 +152,21 @@ Improved Modules
================ ================
dis
---
The :mod:`dis` module is now built around an :class:`Instruction` class that
provides details of individual bytecode operations and a
:func:`get_instructions` iterator that emits the Instruction stream for a
given piece of Python code. The various display tools in the :mod:`dis`
module have been updated to be based on these new components.
The new :class:`dis.Bytecode` class provides an object-oriented API for
inspecting bytecode, both in human-readable form and for iterating over
instructions.
(Contributed by Nick Coghlan, Ryan Kelly and Thomas Kluyver in :issue:`11816`)
doctest doctest
------- -------
......
This diff is collapsed.
This diff is collapsed.
...@@ -74,6 +74,10 @@ Core and Builtins ...@@ -74,6 +74,10 @@ Core and Builtins
Library Library
------- -------
- 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.
- Issue #13831: Embed stringification of remote traceback in local - Issue #13831: Embed stringification of remote traceback in local
traceback raised when pool task raises an exception. traceback raised when pool task raises an exception.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment