Getting to and from ASTs¶
To build an ast from code stored as a string, use ast.parse()
. To turn the
ast into executable code, pass it to compile()
(which can also compile a
string directly).
>>> tree = ast.parse("print('hello world')")
>>> tree
<_ast.Module object at 0x9e3df6c>
>>> exec(compile(tree, filename="<ast>", mode="exec"))
hello world
Modes¶
Python code can be compiled in three modes. The root of the AST depends on the
mode parameter you pass to ast.parse()
, and it must correspond to the
mode parameter when you call compile()
.
- exec - Normal Python code is run with
mode='exec'
. The root of the AST is aast.Module
, whosebody
attribute is a list of nodes. - eval - Single expressions are compiled with
mode='eval'
, and passing them toeval()
will return their result. The root of the AST is anast.Expression
, and itsbody
attribute is a single node, such asast.Call
orast.BinOp
. This is different fromast.Expr
, which holds an expression within an AST. - single - Single statements or expressions can be compiled with
mode='single'
. If it’s an expression,sys.displayhook()
will be called with the result, like when code is run in the interactive shell. The root of the AST is anast.Interactive
, and itsbody
attribute is a list of nodes.
Note
The type_comment
and ignore_types
fields introduced in Python 3.8
are only populated if ast.parse()
is called with type_comment=True
.
Fixing locations¶
To compile an AST, every node must have lineno
and col_offset
attributes.
Nodes produced by parsing regular code already have these, but nodes you create
programmatically don’t. There are a few helper functions for this:
ast.fix_missing_locations()
recursively fills in any missing locations by copying from the parent node. The rough and ready answer.ast.copy_location()
copieslineno
andcol_offset
from one node to another. Useful when you’re replacing a node.ast.increment_lineno()
increaseslineno
for a node and its children, pushing them further down a file.
Going backwards¶
Python itself doesn’t provide a way to turn a compiled code object into an AST, or an AST into a string of code. Some third party tools can do these things:
- astor can convert an AST back to readable Python code.
- Meta also tries to decompile Python bytecode to an AST, but it appears to be unmaintained.
- uncompyle6 is an actively maintained Python decompiler at the time of writing. Its documented interface is a command line program producing Python source code.