ast
— 抽象句法树
¶
源代码: Lib/ast.py
ast
模块帮助 Python 应用程序处理 Python 抽象句法语法树。抽象句法本身可以随着每 Python 发行而改变;此模块以编程方式帮助找出当前语法看起来像什么。
可以生成抽象句法树通过传递
ast.PyCF_ONLY_AST
as a flag to the
compile()
built-in function, or using the
parse()
helper provided in this module. The result will be a tree of objects whose classes all inherit from
ast.AST
. An abstract syntax tree can be compiled into a Python code object using the built-in
compile()
函数。
The abstract grammar is currently defined as follows:
-- ASDL's 4 builtin types are:
-- identifier, int, string, constant
module Python
{
mod = Module(stmt* body, type_ignore* type_ignores)
| Interactive(stmt* body)
| Expression(expr body)
| FunctionType(expr* argtypes, expr returns)
stmt = FunctionDef(identifier name, arguments args,
stmt* body, expr* decorator_list, expr? returns,
string? type_comment)
| AsyncFunctionDef(identifier name, arguments args,
stmt* body, expr* decorator_list, expr? returns,
string? type_comment)
| ClassDef(identifier name,
expr* bases,
keyword* keywords,
stmt* body,
expr* decorator_list)
| Return(expr? value)
| Delete(expr* targets)
| Assign(expr* targets, expr value, string? type_comment)
| AugAssign(expr target, operator op, expr value)
-- 'simple' indicates that we annotate simple name without parens
| AnnAssign(expr target, expr annotation, expr? value, int simple)
-- use 'orelse' because else is a keyword in target languages
| For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)
| AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)
| While(expr test, stmt* body, stmt* orelse)
| If(expr test, stmt* body, stmt* orelse)
| With(withitem* items, stmt* body, string? type_comment)
| AsyncWith(withitem* items, stmt* body, string? type_comment)
| Raise(expr? exc, expr? cause)
| Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)
| Assert(expr test, expr? msg)
| Import(alias* names)
| ImportFrom(identifier? module, alias* names, int? level)
| Global(identifier* names)
| Nonlocal(identifier* names)
| Expr(expr value)
| Pass | Break | Continue
-- col_offset is the byte offset in the utf8 string the parser uses
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
-- BoolOp() can use left & right?
expr = BoolOp(boolop op, expr* values)
| NamedExpr(expr target, expr value)
| BinOp(expr left, operator op, expr right)
| UnaryOp(unaryop op, expr operand)
| Lambda(arguments args, expr body)
| IfExp(expr test, expr body, expr orelse)
| Dict(expr* keys, expr* values)
| Set(expr* elts)
| ListComp(expr elt, comprehension* generators)
| SetComp(expr elt, comprehension* generators)
| DictComp(expr key, expr value, comprehension* generators)
| GeneratorExp(expr elt, comprehension* generators)
-- the grammar constrains where yield expressions can occur
| Await(expr value)
| Yield(expr? value)
| YieldFrom(expr value)
-- need sequences for compare to distinguish between
-- x < 4 < 3 and (x < 4) < 3
| Compare(expr left, cmpop* ops, expr* comparators)
| Call(expr func, expr* args, keyword* keywords)
| FormattedValue(expr value, int? conversion, expr? format_spec)
| JoinedStr(expr* values)
| Constant(constant value, string? kind)
-- the following expression can appear in assignment context
| Attribute(expr value, identifier attr, expr_context ctx)
| Subscript(expr value, expr slice, expr_context ctx)
| Starred(expr value, expr_context ctx)
| Name(identifier id, expr_context ctx)
| List(expr* elts, expr_context ctx)
| Tuple(expr* elts, expr_context ctx)
-- can appear only in Subscript
| Slice(expr? lower, expr? upper, expr? step)
-- col_offset is the byte offset in the utf8 string the parser uses
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
expr_context = Load | Store | Del
boolop = And | Or
operator = Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift
| RShift | BitOr | BitXor | BitAnd | FloorDiv
unaryop = Invert | Not | UAdd | USub
cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn
comprehension = (expr target, expr iter, expr* ifs, int is_async)
excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body)
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
arguments = (arg* posonlyargs, arg* args, arg? vararg, arg* kwonlyargs,
expr* kw_defaults, arg? kwarg, expr* defaults)
arg = (identifier arg, expr? annotation, string? type_comment)
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
-- keyword arguments supplied to call (NULL identifier for **kwargs)
keyword = (identifier? arg, expr value)
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
-- import name with optional 'as' alias.
alias = (identifier name, identifier? asname)
withitem = (expr context_expr, expr? optional_vars)
type_ignore = TypeIgnore(int lineno, string tag)
}
ast.
AST
¶
This is the base of all AST node classes. The actual node classes are derived from the
Parser/Python.asdl
file, which is reproduced
below
. They are defined in the
_ast
C module and re-exported in
ast
.
There is one class defined for each left-hand side symbol in the abstract grammar (for example,
ast.stmt
or
ast.expr
). In addition, there is one class defined for each constructor on the right-hand side; these classes inherit from the classes for the left-hand side trees. For example,
ast.BinOp
继承自
ast.expr
. For production rules with alternatives (aka “sums”), the left-hand side class is abstract: only instances of specific constructor nodes are ever created.
_fields
¶
Each concrete class has an attribute
_fields
which gives the names of all child nodes.
Each instance of a concrete class has one attribute for each child node, of the type as defined in the grammar. For example,
ast.BinOp
instances have an attribute
left
of type
ast.expr
.
If these attributes are marked as optional in the grammar (using a question mark), the value might be
None
. If the attributes can have zero-or-more values (marked with an asterisk), the values are represented as Python lists. All possible attributes must be present and have valid values when compiling an AST with
compile()
.
lineno
¶
col_offset
¶
end_lineno
¶
end_col_offset
¶
实例化的
ast.expr
and
ast.stmt
subclasses have
lineno
,
col_offset
,
end_lineno
,和
end_col_offset
attributes. The
lineno
and
end_lineno
are the first and last line numbers of the source text span (1-indexed so the first line is line 1), and the
col_offset
and
end_col_offset
are the corresponding UTF-8 byte offsets of the first and last tokens that generated the node. The UTF-8 offset is recorded because the parser uses UTF-8 internally.
Note that the end positions are not required by the compiler and are therefore optional. The end offset is
after
the last symbol, for example one can get the source segment of a one-line expression node using
source_line[node.col_offset : node.end_col_offset]
.
The constructor of a class
ast.T
parses its arguments as follows:
If there are positional arguments, there must be as many as there are items in
T._fields
; they will be assigned as attributes of these names.
If there are keyword arguments, they will set the attributes of the same names to the given values.
例如,要创建和填充
ast.UnaryOp
节点,可以使用
node = ast.UnaryOp()
node.op = ast.USub()
node.operand = ast.Constant()
node.operand.value = 5
node.operand.lineno = 0
node.operand.col_offset = 0
node.lineno = 0
node.col_offset = 0
or the more compact
node = ast.UnaryOp(ast.USub(), ast.Constant(5, lineno=0, col_offset=0),
lineno=0, col_offset=0)
3.8 版改变:
类
ast.Constant
is now used for all constants.
3.9 版改变: Simple indices are represented by their value, extended slices are represented as tuples.
从 3.8 版起弃用:
旧类
ast.Num
,
ast.Str
,
ast.Bytes
,
ast.NameConstant
and
ast.Ellipsis
are still available, but they will be removed in future Python releases. In the meantime, instantiating them will return an instance of a different class.
从 3.9 版起弃用:
旧类
ast.Index
and
ast.ExtSlice
are still available, but they will be removed in future Python releases. In the meantime, instantiating them will return an instance of a different class.
注意
The descriptions of the specific node classes displayed here were initially adapted from the fantastic Green Tree Snakes project and all its contributors.
ast.
常量
(
value
)
¶
常量值。
value
属性在
Constant
literal contains the Python object it represents. The values represented can be simple types such as a number, string or
None
, but also immutable container types (tuples and frozensets) if all of their elements are constant.
>>> print(ast.dump(ast.parse('123', mode='eval'), indent=4))
Expression(
body=Constant(value=123))
ast.
FormattedValue
(
value
,
conversion
,
format_spec
)
¶
Node representing a single formatting field in an f-string. If the string contains a single formatting field and nothing else the node can be isolated otherwise it appears in
JoinedStr
.
value
is any expression node (such as a literal, a variable, or a function call).
conversion
是整数:
-1: no formatting
115:
!s
string formatting
114:
!r
repr formatting
97:
!a
ascii formatting
format_spec
是
JoinedStr
node representing the formatting of the value, or
None
if no format was specified. Both
conversion
and
format_spec
can be set at the same time.
ast.
JoinedStr
(
values
)
¶
An f-string, comprising a series of
FormattedValue
and
Constant
节点。
>>> print(ast.dump(ast.parse('f"sin({a}) is {sin(a):.3}"', mode='eval'), indent=4))
Expression(
body=JoinedStr(
values=[
Constant(value='sin('),
FormattedValue(
value=Name(id='a', ctx=Load()),
conversion=-1),
Constant(value=') is '),
FormattedValue(
value=Call(
func=Name(id='sin', ctx=Load()),
args=[
Name(id='a', ctx=Load())],
keywords=[]),
conversion=-1,
format_spec=JoinedStr(
values=[
Constant(value='.3')]))]))
ast.
List
(
elts
,
ctx
)
¶
ast.
Tuple
(
elts
,
ctx
)
¶
列表或元组。
elts
holds a list of nodes representing the elements.
ctx
is
Store
if the container is an assignment target (i.e.
(x,y)=something
),和
Load
否则。
>>> print(ast.dump(ast.parse('[1, 2, 3]', mode='eval'), indent=4))
Expression(
body=List(
elts=[
Constant(value=1),
Constant(value=2),
Constant(value=3)],
ctx=Load()))
>>> print(ast.dump(ast.parse('(1, 2, 3)', mode='eval'), indent=4))
Expression(
body=Tuple(
elts=[
Constant(value=1),
Constant(value=2),
Constant(value=3)],
ctx=Load()))
ast.
Set
(
elts
)
¶
A set.
elts
holds a list of nodes representing the set’s elements.
>>> print(ast.dump(ast.parse('{1, 2, 3}', mode='eval'), indent=4))
Expression(
body=Set(
elts=[
Constant(value=1),
Constant(value=2),
Constant(value=3)]))
ast.
Dict
(
keys
,
values
)
¶
A dictionary.
keys
and
values
hold lists of nodes representing the keys and the values respectively, in matching order (what would be returned when calling
dictionary.keys()
and
dictionary.values()
).
When doing dictionary unpacking using dictionary literals the expression to be expanded goes in the
values
list, with a
None
at the corresponding position in
keys
.
>>> print(ast.dump(ast.parse('{"a":1, **d}', mode='eval'), indent=4))
Expression(
body=Dict(
keys=[
Constant(value='a'),
None],
values=[
Constant(value=1),
Name(id='d', ctx=Load())]))
ast.
名称
(
id
,
ctx
)
¶
A variable name.
id
holds the name as a string, and
ctx
is one of the following types.
ast.
Load
¶
ast.
Store
¶
ast.
Del
¶
Variable references can be used to load the value of a variable, to assign a new value to it, or to delete it. Variable references are given a context to distinguish these cases.
>>> print(ast.dump(ast.parse('a'), indent=4))
Module(
body=[
Expr(
value=Name(id='a', ctx=Load()))],
type_ignores=[])
>>> print(ast.dump(ast.parse('a = 1'), indent=4))
Module(
body=[
Assign(
targets=[
Name(id='a', ctx=Store())],
value=Constant(value=1))],
type_ignores=[])
>>> print(ast.dump(ast.parse('del a'), indent=4))
Module(
body=[
Delete(
targets=[
Name(id='a', ctx=Del())])],
type_ignores=[])
ast.
Starred
(
value
,
ctx
)
¶
A
*var
variable reference.
value
holds the variable, typically a
Name
node. This type must be used when building a
Call
node with
*args
.
>>> print(ast.dump(ast.parse('a, *b = it'), indent=4))
Module(
body=[
Assign(
targets=[
Tuple(
elts=[
Name(id='a', ctx=Store()),
Starred(
value=Name(id='b', ctx=Store()),
ctx=Store())],
ctx=Store())],
value=Name(id='it', ctx=Load()))],
type_ignores=[])
ast.
Expr
(
value
)
¶
When an expression, such as a function call, appears as a statement by itself with its return value not used or stored, it is wrapped in this container.
value
holds one of the other nodes in this section, a
Constant
,
Name
,
Lambda
,
Yield
or
YieldFrom
node.
>>> print(ast.dump(ast.parse('-a'), indent=4))
Module(
body=[
Expr(
value=UnaryOp(
op=USub(),
operand=Name(id='a', ctx=Load())))],
type_ignores=[])
ast.
UnaryOp
(
op
,
operand
)
¶
A unary operation.
op
is the operator, and
operand
any expression node.
ast.
UAdd
¶
ast.
USub
¶
ast.
Not
¶
ast.
Invert
¶
Unary operator tokens.
Not
是
not
keyword,
Invert
是
~
operator.
>>> print(ast.dump(ast.parse('not x', mode='eval'), indent=4))
Expression(
body=UnaryOp(
op=Not(),
operand=Name(id='x', ctx=Load())))
ast.
BinOp
(
left
,
op
,
right
)
¶
A binary operation (like addition or division).
op
is the operator, and
left
and
right
are any expression nodes.
>>> print(ast.dump(ast.parse('x + y', mode='eval'), indent=4))
Expression(
body=BinOp(
left=Name(id='x', ctx=Load()),
op=Add(),
right=Name(id='y', ctx=Load())))
ast.
添加
¶
ast.
Sub
¶
ast.
Mult
¶
ast.
Div
¶
ast.
FloorDiv
¶
ast.
Mod
¶
ast.
Pow
¶
ast.
LShift
¶
ast.
RShift
¶
ast.
BitOr
¶
ast.
BitXor
¶
ast.
BitAnd
¶
ast.
MatMult
¶
Binary operator tokens.
ast.
BoolOp
(
op
,
values
)
¶
A boolean operation, ‘or’ or ‘and’.
op
is
Or
or
And
.
values
are the values involved. Consecutive operations with the same operator, such as
a or b or c
, are collapsed into one node with several values.
This doesn’t include
not
, which is a
UnaryOp
.
>>> print(ast.dump(ast.parse('x or y', mode='eval'), indent=4))
Expression(
body=BoolOp(
op=Or(),
values=[
Name(id='x', ctx=Load()),
Name(id='y', ctx=Load())]))
ast.
比较
(
left
,
ops
,
comparators
)
¶
A comparison of two or more values.
left
is the first value in the comparison,
ops
the list of operators, and
comparators
the list of values after the first element in the comparison.
>>> print(ast.dump(ast.parse('1 <= a < 10', mode='eval'), indent=4))
Expression(
body=Compare(
left=Constant(value=1),
ops=[
LtE(),
Lt()],
comparators=[
Name(id='a', ctx=Load()),
Constant(value=10)]))
ast.
Eq
¶
ast.
NotEq
¶
ast.
Lt
¶
ast.
LtE
¶
ast.
Gt
¶
ast.
GtE
¶
ast.
Is
¶
ast.
IsNot
¶
ast.
在
¶
ast.
NotIn
¶
Comparison operator tokens.
ast.
调用
(
func
,
args
,
keywords
,
starargs
,
kwargs
)
¶
A function call.
func
is the function, which will often be a
Name
or
Attribute
object. Of the arguments:
args
holds a list of the arguments passed by position.
keywords
holds a list of
keyword
objects representing arguments passed by keyword.
当创建
Call
node,
args
and
keywords
are required, but they can be empty lists.
starargs
and
kwargs
are optional.
>>> print(ast.dump(ast.parse('func(a, b=c, *d, **e)', mode='eval'), indent=4))
Expression(
body=Call(
func=Name(id='func', ctx=Load()),
args=[
Name(id='a', ctx=Load()),
Starred(
value=Name(id='d', ctx=Load()),
ctx=Load())],
keywords=[
keyword(
arg='b',
value=Name(id='c', ctx=Load())),
keyword(
value=Name(id='e', ctx=Load()))]))
ast.
keyword
(
arg
,
value
)
¶
A keyword argument to a function call or class definition.
arg
is a raw string of the parameter name,
value
is a node to pass in.
ast.
IfExp
(
test
,
body
,
orelse
)
¶
An expression such as
a if b else c
. Each field holds a single node, so in the following example, all three are
Name
节点。
>>> print(ast.dump(ast.parse('a if b else c', mode='eval'), indent=4))
Expression(
body=IfExp(
test=Name(id='b', ctx=Load()),
body=Name(id='a', ctx=Load()),
orelse=Name(id='c', ctx=Load())))
ast.
属性
(
value
,
attr
,
ctx
)
¶
Attribute access, e.g.
d.keys
.
value
is a node, typically a
Name
.
attr
is a bare string giving the name of the attribute, and
ctx
is
Load
,
Store
or
Del
according to how the attribute is acted on.
>>> print(ast.dump(ast.parse('snake.colour', mode='eval'), indent=4))
Expression(
body=Attribute(
value=Name(id='snake', ctx=Load()),
attr='colour',
ctx=Load()))
ast.
NamedExpr
(
target
,
value
)
¶
A named expression. This AST node is produced by the assignment expressions operator (also known as the walrus operator). As opposed to the
Assignnode in which the first argument can be multiple nodes, in this case bothtargetandvaluemust be single nodes.
>>> print(ast.dump(ast.parse('(x := 4)', mode='eval'), indent=4))
Expression(
body=NamedExpr(
target=Name(id='x', ctx=Store()),
value=Constant(value=4)))
ast.
Subscript
(
value
,
slice
,
ctx
)
¶
A subscript, such as
l[1]
.
value
is the subscripted object (usually sequence or mapping).
slice
is an index, slice or key. It can be a
Tuple
and contain a
Slice
.
ctx
is
Load
,
Store
or
Del
according to the action performed with the subscript.
>>> print(ast.dump(ast.parse('l[1:2, 3]', mode='eval'), indent=4))
Expression(
body=Subscript(
value=Name(id='l', ctx=Load()),
slice=Tuple(
elts=[
Slice(
lower=Constant(value=1),
upper=Constant(value=2)),
Constant(value=3)],
ctx=Load()),
ctx=Load()))
ast.
Slice
(
lower
,
upper
,
step
)
¶
Regular slicing (on the form
lower:upper
or
lower:upper:step
). Can occur only inside the
slice
field of
Subscript
, either directly or as an element of
Tuple
.
>>> print(ast.dump(ast.parse('l[1:2]', mode='eval'), indent=4))
Expression(
body=Subscript(
value=Name(id='l', ctx=Load()),
slice=Slice(
lower=Constant(value=1),
upper=Constant(value=2)),
ctx=Load()))
ast.
ListComp
(
elt
,
generators
)
¶
ast.
SetComp
(
elt
,
generators
)
¶
ast.
GeneratorExp
(
elt
,
generators
)
¶
ast.
DictComp
(
key
,
value
,
generators
)
¶
List and set comprehensions, generator expressions, and dictionary comprehensions.
elt
(或
key
and
value
) is a single node representing the part that will be evaluated for each item.
generators
is a list of
comprehension
节点。
>>> print(ast.dump(ast.parse('[x for x in numbers]', mode='eval'), indent=4))
Expression(
body=ListComp(
elt=Name(id='x', ctx=Load()),
generators=[
comprehension(
target=Name(id='x', ctx=Store()),
iter=Name(id='numbers', ctx=Load()),
ifs=[],
is_async=0)]))
>>> print(ast.dump(ast.parse('{x: x**2 for x in numbers}', mode='eval'), indent=4))
Expression(
body=DictComp(
key=Name(id='x', ctx=Load()),
value=BinOp(
left=Name(id='x', ctx=Load()),
op=Pow(),
right=Constant(value=2)),
generators=[
comprehension(
target=Name(id='x', ctx=Store()),
iter=Name(id='numbers', ctx=Load()),
ifs=[],
is_async=0)]))
>>> print(ast.dump(ast.parse('{x for x in numbers}', mode='eval'), indent=4))
Expression(
body=SetComp(
elt=Name(id='x', ctx=Load()),
generators=[
comprehension(
target=Name(id='x', ctx=Store()),
iter=Name(id='numbers', ctx=Load()),
ifs=[],
is_async=0)]))
ast.
comprehension
(
target
,
iter
,
ifs
,
is_async
)
¶
One
for
clause in a comprehension.
target
is the reference to use for each element - typically a
Name
or
Tuple
node.
iter
is the object to iterate over.
ifs
is a list of test expressions: each
for
clause can have multiple
ifs
.
is_async
indicates a comprehension is asynchronous (using an
async for
而不是
for
). The value is an integer (0 or 1).
>>> print(ast.dump(ast.parse('[ord(c) for line in file for c in line]', mode='eval'),
... indent=4)) # Multiple comprehensions in one.
Expression(
body=ListComp(
elt=Call(
func=Name(id='ord', ctx=Load()),
args=[
Name(id='c', ctx=Load())],
keywords=[]),
generators=[
comprehension(
target=Name(id='line', ctx=Store()),
iter=Name(id='file', ctx=Load()),
ifs=[],
is_async=0),
comprehension(
target=Name(id='c', ctx=Store()),
iter=Name(id='line', ctx=Load()),
ifs=[],
is_async=0)]))
>>> print(ast.dump(ast.parse('(n**2 for n in it if n>5 if n<10)', mode='eval'),
... indent=4)) # generator comprehension
Expression(
body=GeneratorExp(
elt=BinOp(
left=Name(id='n', ctx=Load()),
op=Pow(),
right=Constant(value=2)),
generators=[
comprehension(
target=Name(id='n', ctx=Store()),
iter=Name(id='it', ctx=Load()),
ifs=[
Compare(
left=Name(id='n', ctx=Load()),
ops=[
Gt()],
comparators=[
Constant(value=5)]),
Compare(
left=Name(id='n', ctx=Load()),
ops=[
Lt()],
comparators=[
Constant(value=10)])],
is_async=0)]))
>>> print(ast.dump(ast.parse('[i async for i in soc]', mode='eval'),
... indent=4)) # Async comprehension
Expression(
body=ListComp(
elt=Name(id='i', ctx=Load()),
generators=[
comprehension(
target=Name(id='i', ctx=Store()),
iter=Name(id='soc', ctx=Load()),
ifs=[],
is_async=1)]))
ast.
Assign
(
targets
,
value
,
type_comment
)
¶
An assignment.
targets
is a list of nodes, and
value
is a single node.
Multiple nodes in
targets
represents assigning the same value to each. Unpacking is represented by putting a
Tuple
or
List
within
targets
.
type_comment
¶
type_comment
is an optional string with the type annotation as a comment.
>>> print(ast.dump(ast.parse('a = b = 1'), indent=4)) # Multiple assignment
Module(
body=[
Assign(
targets=[
Name(id='a', ctx=Store()),
Name(id='b', ctx=Store())],
value=Constant(value=1))],
type_ignores=[])
>>> print(ast.dump(ast.parse('a,b = c'), indent=4)) # Unpacking
Module(
body=[
Assign(
targets=[
Tuple(
elts=[
Name(id='a', ctx=Store()),
Name(id='b', ctx=Store())],
ctx=Store())],
value=Name(id='c', ctx=Load()))],
type_ignores=[])
ast.
AnnAssign
(
target
,
annotation
,
value
,
simple
)
¶
An assignment with a type annotation.
target
is a single node and can be a
Name
,
Attribute
或
Subscript
.
annotation
is the annotation, such as a
Constant
or
Name
node.
value
is a single optional node.
simple
is a boolean integer set to True for a
Name
node in
target
that do not appear in between parenthesis and are hence pure names and not expressions.
>>> print(ast.dump(ast.parse('c: int'), indent=4))
Module(
body=[
AnnAssign(
target=Name(id='c', ctx=Store()),
annotation=Name(id='int', ctx=Load()),
simple=1)],
type_ignores=[])
>>> print(ast.dump(ast.parse('(a): int = 1'), indent=4)) # Annotation with parenthesis
Module(
body=[
AnnAssign(
target=Name(id='a', ctx=Store()),
annotation=Name(id='int', ctx=Load()),
value=Constant(value=1),
simple=0)],
type_ignores=[])
>>> print(ast.dump(ast.parse('a.b: int'), indent=4)) # Attribute annotation
Module(
body=[
AnnAssign(
target=Attribute(
value=Name(id='a', ctx=Load()),
attr='b',
ctx=Store()),
annotation=Name(id='int', ctx=Load()),
simple=0)],
type_ignores=[])
>>> print(ast.dump(ast.parse('a[1]: int'), indent=4)) # Subscript annotation
Module(
body=[
AnnAssign(
target=Subscript(
value=Name(id='a', ctx=Load()),
slice=Constant(value=1),
ctx=Store()),
annotation=Name(id='int', ctx=Load()),
simple=0)],
type_ignores=[])
ast.
AugAssign
(
target
,
op
,
value
)
¶
Augmented assignment, such as
a += 1
. In the following example,
target
是
Name
node for
x
(with the
Store
context),
op
is
Add
,和
value
是
Constant
with value for 1.
target
attribute connot be of class
Tuple
or
List
, unlike the targets of
Assign
.
>>> print(ast.dump(ast.parse('x += 2'), indent=4))
Module(
body=[
AugAssign(
target=Name(id='x', ctx=Store()),
op=Add(),
value=Constant(value=2))],
type_ignores=[])
ast.
引发
(
exc
,
cause
)
¶
A
raise
语句。
exc
is the exception object to be raised, normally a
Call
or
Name
,或
None
for a standalone
raise
.
cause
is the optional part for
y
in
raise x from y
.
>>> print(ast.dump(ast.parse('raise x from y'), indent=4))
Module(
body=[
Raise(
exc=Name(id='x', ctx=Load()),
cause=Name(id='y', ctx=Load()))],
type_ignores=[])
ast.
Assert
(
test
,
msg
)
¶
An assertion.
test
holds the condition, such as a
Compare
node.
msg
holds the failure message.
>>> print(ast.dump(ast.parse('assert x,y'), indent=4))
Module(
body=[
Assert(
test=Name(id='x', ctx=Load()),
msg=Name(id='y', ctx=Load()))],
type_ignores=[])
ast.
Delete
(
targets
)
¶
Represents a
del
语句。
targets
is a list of nodes, such as
Name
,
Attribute
or
Subscript
节点。
>>> print(ast.dump(ast.parse('del x,y,z'), indent=4))
Module(
body=[
Delete(
targets=[
Name(id='x', ctx=Del()),
Name(id='y', ctx=Del()),
Name(id='z', ctx=Del())])],
type_ignores=[])
ast.
Pass
¶
A
pass
语句。
>>> print(ast.dump(ast.parse('pass'), indent=4))
Module(
body=[
Pass()],
type_ignores=[])
Other statements which are only applicable inside functions or loops are described in other sections.
ast.
Import
(
名称
)
¶
An import statement.
names
is a list of
alias
节点。
>>> print(ast.dump(ast.parse('import x,y,z'), indent=4))
Module(
body=[
Import(
names=[
alias(name='x'),
alias(name='y'),
alias(name='z')])],
type_ignores=[])
ast.
ImportFrom
(
module
,
名称
,
level
)
¶
Represents
from x import y
.
module
is a raw string of the ‘from’ name, without any leading dots, or
None
for statements such as
from . import foo
.
level
is an integer holding the level of the relative import (0 means absolute import).
>>> print(ast.dump(ast.parse('from y import x,y,z'), indent=4))
Module(
body=[
ImportFrom(
module='y',
names=[
alias(name='x'),
alias(name='y'),
alias(name='z')],
level=0)],
type_ignores=[])
ast.
alias
(
name
,
asname
)
¶
Both parameters are raw strings of the names.
asname
可以是
None
if the regular name is to be used.
>>> print(ast.dump(ast.parse('from ..foo.bar import a as b, c'), indent=4))
Module(
body=[
ImportFrom(
module='foo.bar',
names=[
alias(name='a', asname='b'),
alias(name='c')],
level=2)],
type_ignores=[])
注意
Optional clauses such as
else
are stored as an empty list if they’re not present.
ast.
若
(
test
,
body
,
orelse
)
¶
An
if
语句。
test
holds a single node, such as a
Compare
node.
body
and
orelse
each hold a list of nodes.
elif
clauses don’t have a special representation in the AST, but rather appear as extra
If
nodes within the
orelse
section of the previous one.
>>> print(ast.dump(ast.parse("""
... if x:
... ...
... elif y:
... ...
... else:
... ...
... """), indent=4))
Module(
body=[
If(
test=Name(id='x', ctx=Load()),
body=[
Expr(
value=Constant(value=Ellipsis))],
orelse=[
If(
test=Name(id='y', ctx=Load()),
body=[
Expr(
value=Constant(value=Ellipsis))],
orelse=[
Expr(
value=Constant(value=Ellipsis))])])],
type_ignores=[])
ast.
For
(
target
,
iter
,
body
,
orelse
,
type_comment
)
¶
A
for
loop.
target
holds the variable(s) the loop assigns to, as a single
Name
,
Tuple
or
List
node.
iter
holds the item to be looped over, again as a single node.
body
and
orelse
contain lists of nodes to execute. Those in
orelse
are executed if the loop finishes normally, rather than via a
break
语句。
type_comment
¶
type_comment
is an optional string with the type annotation as a comment.
>>> print(ast.dump(ast.parse("""
... for x in y:
... ...
... else:
... ...
... """), indent=4))
Module(
body=[
For(
target=Name(id='x', ctx=Store()),
iter=Name(id='y', ctx=Load()),
body=[
Expr(
value=Constant(value=Ellipsis))],
orelse=[
Expr(
value=Constant(value=Ellipsis))])],
type_ignores=[])
ast.
While
(
test
,
body
,
orelse
)
¶
A
while
loop.
test
holds the condition, such as a
Compare
node.
>> print(ast.dump(ast.parse("""
... while x:
... ...
... else:
... ...
... """), indent=4))
Module(
body=[
While(
test=Name(id='x', ctx=Load()),
body=[
Expr(
value=Constant(value=Ellipsis))],
orelse=[
Expr(
value=Constant(value=Ellipsis))])],
type_ignores=[])
ast.
Break
¶
ast.
Continue
¶
break
and
continue
语句。
>>> print(ast.dump(ast.parse("""\
... for a in b:
... if a > 5:
... break
... else:
... continue
...
... """), indent=4))
Module(
body=[
For(
target=Name(id='a', ctx=Store()),
iter=Name(id='b', ctx=Load()),
body=[
If(
test=Compare(
left=Name(id='a', ctx=Load()),
ops=[
Gt()],
comparators=[
Constant(value=5)]),
body=[
Break()],
orelse=[
Continue()])],
orelse=[])],
type_ignores=[])
ast.
Try
(
body
,
handlers
,
orelse
,
finalbody
)
¶
try
blocks. All attributes are list of nodes to execute, except for
handlers
, which is a list of
ExceptHandler
节点。
>>> print(ast.dump(ast.parse("""
... try:
... ...
... except Exception:
... ...
... except OtherException as e:
... ...
... else:
... ...
... finally:
... ...
... """), indent=4))
Module(
body=[
Try(
body=[
Expr(
value=Constant(value=Ellipsis))],
handlers=[
ExceptHandler(
type=Name(id='Exception', ctx=Load()),
body=[
Expr(
value=Constant(value=Ellipsis))]),
ExceptHandler(
type=Name(id='OtherException', ctx=Load()),
name='e',
body=[
Expr(
value=Constant(value=Ellipsis))])],
orelse=[
Expr(
value=Constant(value=Ellipsis))],
finalbody=[
Expr(
value=Constant(value=Ellipsis))])],
type_ignores=[])
ast.
ExceptHandler
(
type
,
name
,
body
)
¶
A single
except
子句。
type
is the exception type it will match, typically a
Name
node (or
None
for a catch-all
except:
clause).
name
is a raw string for the name to hold the exception, or
None
if the clause doesn’t have
as foo
.
body
is a list of nodes.
>>> print(ast.dump(ast.parse("""\
... try:
... a + 1
... except TypeError:
... pass
... """), indent=4))
Module(
body=[
Try(
body=[
Expr(
value=BinOp(
left=Name(id='a', ctx=Load()),
op=Add(),
right=Constant(value=1)))],
handlers=[
ExceptHandler(
type=Name(id='TypeError', ctx=Load()),
body=[
Pass()])],
orelse=[],
finalbody=[])],
type_ignores=[])
ast.
With
(
items
,
body
,
type_comment
)
¶
A
with
块。
items
is a list of
withitem
nodes representing the context managers, and
body
is the indented block inside the context.
type_comment
¶
type_comment
is an optional string with the type annotation as a comment.
ast.
withitem
(
context_expr
,
optional_vars
)
¶
A single context manager in a
with
块。
context_expr
is the context manager, often a
Call
node.
optional_vars
是
Name
,
Tuple
or
List
为
as foo
part, or
None
if that isn’t used.
>>> print(ast.dump(ast.parse("""\
... with a as b, c as d:
... something(b, d)
... """), indent=4))
Module(
body=[
With(
items=[
withitem(
context_expr=Name(id='a', ctx=Load()),
optional_vars=Name(id='b', ctx=Store())),
withitem(
context_expr=Name(id='c', ctx=Load()),
optional_vars=Name(id='d', ctx=Store()))],
body=[
Expr(
value=Call(
func=Name(id='something', ctx=Load()),
args=[
Name(id='b', ctx=Load()),
Name(id='d', ctx=Load())],
keywords=[]))])],
type_ignores=[])
ast.
FunctionDef
(
name
,
args
,
body
,
decorator_list
,
返回
,
type_comment
)
¶
A function definition.
name
is a raw string of the function name.
args
是
arguments
node.
body
is the list of nodes inside the function.
decorator_list
is the list of decorators to be applied, stored outermost first (i.e. the first in the list will be applied last).
returns
is the return annotation.
type_comment
¶
type_comment
is an optional string with the type annotation as a comment.
ast.
Lambda
(
args
,
body
)
¶
lambda
is a minimal function definition that can be used inside an expression. Unlike
FunctionDef
,
body
holds a single node.
>>> print(ast.dump(ast.parse('lambda x,y: ...'), indent=4))
Module(
body=[
Expr(
value=Lambda(
args=arguments(
posonlyargs=[],
args=[
arg(arg='x'),
arg(arg='y')],
kwonlyargs=[],
kw_defaults=[],
defaults=[]),
body=Constant(value=Ellipsis)))],
type_ignores=[])
ast.
arguments
(
posonlyargs
,
args
,
vararg
,
kwonlyargs
,
kw_defaults
,
kwarg
,
defaults
)
¶
The arguments for a function.
posonlyargs
,
args
and
kwonlyargs
are lists of
arg
节点。
vararg
and
kwarg
are single
arg
nodes, referring to the
*args, **kwargs
参数。
kw_defaults
is a list of default values for keyword-only arguments. If one is
None
, the corresponding argument is required.
defaults
is a list of default values for arguments that can be passed positionally. If there are fewer defaults, they correspond to the last n arguments.
ast.
arg
(
arg
,
annotation
,
type_comment
)
¶
A single argument in a list.
arg
is a raw string of the argument name,
annotation
is its annotation, such as a
Str
or
Name
node.
type_comment
¶
type_comment
is an optional string with the type annotation as a comment
>>> print(ast.dump(ast.parse("""\
... @decorator1
... @decorator2
... def f(a: 'annotation', b=1, c=2, *d, e, f=3, **g) -> 'return annotation':
... pass
... """), indent=4))
Module(
body=[
FunctionDef(
name='f',
args=arguments(
posonlyargs=[],
args=[
arg(
arg='a',
annotation=Constant(value='annotation')),
arg(arg='b'),
arg(arg='c')],
vararg=arg(arg='d'),
kwonlyargs=[
arg(arg='e'),
arg(arg='f')],
kw_defaults=[
None,
Constant(value=3)],
kwarg=arg(arg='g'),
defaults=[
Constant(value=1),
Constant(value=2)]),
body=[
Pass()],
decorator_list=[
Name(id='decorator1', ctx=Load()),
Name(id='decorator2', ctx=Load())],
returns=Constant(value='return annotation'))],
type_ignores=[])
ast.
返回
(
value
)
¶
A
return
语句。
>>> print(ast.dump(ast.parse('return 4'), indent=4))
Module(
body=[
Return(
value=Constant(value=4))],
type_ignores=[])
ast.
Yield
(
value
)
¶
ast.
YieldFrom
(
value
)
¶
A
yield
or
yield from
expression. Because these are expressions, they must be wrapped in a
Expr
node if the value sent back is not used.
>>> print(ast.dump(ast.parse('yield x'), indent=4))
Module(
body=[
Expr(
value=Yield(
value=Name(id='x', ctx=Load())))],
type_ignores=[])
>>> print(ast.dump(ast.parse('yield from x'), indent=4))
Module(
body=[
Expr(
value=YieldFrom(
value=Name(id='x', ctx=Load())))],
type_ignores=[])
ast.
Global
(
名称
)
¶
ast.
Nonlocal
(
名称
)
¶
global
and
nonlocal
语句。
names
is a list of raw strings.
>>> print(ast.dump(ast.parse('global x,y,z'), indent=4))
Module(
body=[
Global(
names=[
'x',
'y',
'z'])],
type_ignores=[])
>>> print(ast.dump(ast.parse('nonlocal x,y,z'), indent=4))
Module(
body=[
Nonlocal(
names=[
'x',
'y',
'z'])],
type_ignores=[])
ast.
ClassDef
(
name
,
bases
,
keywords
,
starargs
,
kwargs
,
body
,
decorator_list
)
¶
A class definition.
name
is a raw string for the class name
bases
is a list of nodes for explicitly specified base classes.
keywords
is a list of
keyword
nodes, principally for ‘metaclass’. Other keywords will be passed to the metaclass, as per
PEP-3115
.
starargs
and
kwargs
are each a single node, as in a function call. starargs will be expanded to join the list of base classes, and kwargs will be passed to the metaclass.
body
is a list of nodes representing the code within the class definition.
decorator_list
is a list of nodes, as in
FunctionDef
.
>>> print(ast.dump(ast.parse("""\
... @decorator1
... @decorator2
... class Foo(base1, base2, metaclass=meta):
... pass
... """), indent=4))
Module(
body=[
ClassDef(
name='Foo',
bases=[
Name(id='base1', ctx=Load()),
Name(id='base2', ctx=Load())],
keywords=[
keyword(
arg='metaclass',
value=Name(id='meta', ctx=Load()))],
body=[
Pass()],
decorator_list=[
Name(id='decorator1', ctx=Load()),
Name(id='decorator2', ctx=Load())])],
type_ignores=[])
ast.
AsyncFunctionDef
(
name
,
args
,
body
,
decorator_list
,
返回
,
type_comment
)
¶
An
async def
function definition. Has the same fields as
FunctionDef
.
ast.
Await
(
value
)
¶
An
await
表达式。
value
is what it waits for. Only valid in the body of an
AsyncFunctionDef
.
>>> print(ast.dump(ast.parse("""\
... async def f():
... await other_func()
... """), indent=4))
Module(
body=[
AsyncFunctionDef(
name='f',
args=arguments(
posonlyargs=[],
args=[],
kwonlyargs=[],
kw_defaults=[],
defaults=[]),
body=[
Expr(
value=Await(
value=Call(
func=Name(id='other_func', ctx=Load()),
args=[],
keywords=[])))],
decorator_list=[])],
type_ignores=[])
ast.
AsyncFor
(
target
,
iter
,
body
,
orelse
,
type_comment
)
¶
ast.
AsyncWith
(
items
,
body
,
type_comment
)
¶
async for
循环和
async with
上下文管理器。它们拥有相同的字段如
For
and
With
, respectively. Only valid in the body of an
AsyncFunctionDef
.
注意
当剖析字符串通过
ast.parse()
, operator nodes (subclasses of
ast.operator
,
ast.unaryop
,
ast.cmpop
,
ast.boolop
and
ast.expr_context
) on the returned tree will be singletons. Changes to one will be reflected in all other occurrences of the same value (e.g.
ast.Add
).
ast
帮手
¶
Apart from the node classes, the
ast
module defines these utility functions and classes for traversing abstract syntax trees:
ast.
parse
(
source
,
filename='<unknown>'
,
mode='exec'
,
*
,
type_comments=False
,
feature_version=None
)
¶
Parse the source into an AST node. Equivalent to
compile(source,
filename, mode, ast.PyCF_ONLY_AST)
.
若
type_comments=True
is given, the parser is modified to check and return type comments as specified by
PEP 484
and
PEP 526
. This is equivalent to adding
ast.PyCF_TYPE_COMMENTS
to the flags passed to
compile()
. This will report syntax errors for misplaced type comments. Without this flag, type comments will be ignored, and the
type_comment
field on selected AST nodes will always be
None
. In addition, the locations of
# type:
ignore
comments will be returned as the
type_ignores
attribute of
Module
(otherwise it is always an empty list).
In addition, if
mode
is
'func_type'
, the input syntax is modified to correspond to
PEP 484
“signature type comments”, e.g.
(str, int) -> List[str]
.
Also, setting
feature_version
to a tuple
(major, minor)
will attempt to parse using that Python version’s grammar. Currently
major
must equal to
3
. For example, setting
feature_version=(3, 4)
will allow the use of
async
and
await
as variable names. The lowest supported version is
(3, 4)
; the highest is
sys.version_info[0:2]
.
警告
It is possible to crash the Python interpreter with a sufficiently large/complex string due to stack depth limitations in Python’s AST compiler.
3.8 版改变:
添加
type_comments
,
mode='func_type'
and
feature_version
.
ast.
unparse
(
ast_obj
)
¶
Unparse an
ast.AST
object and generate a string with code that would produce an equivalent
ast.AST
object if parsed back with
ast.parse()
.
警告
The produced code string will not necessarily be equal to the original code that generated the
ast.AST
object (without any compiler optimizations, such as constant tuples/frozensets).
警告
Trying to unparse a highly complex expression would result with
RecursionError
.
3.9 版新增。
ast.
literal_eval
(
node_or_string
)
¶
Safely evaluate an expression node or a string containing a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, and
None
.
This can be used for safely evaluating strings containing Python values from untrusted sources without the need to parse the values oneself. It is not capable of evaluating arbitrarily complex expressions, for example involving operators or indexing.
警告
It is possible to crash the Python interpreter with a sufficiently large/complex string due to stack depth limitations in Python’s AST compiler.
3.2 版改变: Now allows bytes and set literals.
3.9 版改变:
Now supports creating empty sets with
'set()'
.
ast.
get_docstring
(
node
,
clean=True
)
¶
Return the docstring of the given
node
(which must be a
FunctionDef
,
AsyncFunctionDef
,
ClassDef
,或
Module
node), or
None
if it has no docstring. If
clean
is true, clean up the docstring’s indentation with
inspect.cleandoc()
.
3.5 版改变:
AsyncFunctionDef
is now supported.
ast.
get_source_segment
(
source
,
node
,
*
,
padded=False
)
¶
Get source code segment of the
source
that generated
node
. If some location information (
lineno
,
end_lineno
,
col_offset
,或
end_col_offset
) is missing, return
None
.
若
padded
is
True
, the first line of a multi-line statement will be padded with spaces to match its original position.
3.8 版新增。
ast.
fix_missing_locations
(
node
)
¶
When you compile a node tree with
compile()
, the compiler expects
lineno
and
col_offset
attributes for every node that supports them. This is rather tedious to fill in for generated nodes, so this helper adds these attributes recursively where not already set, by setting them to the values of the parent node. It works recursively starting at
node
.
ast.
increment_lineno
(
node
,
n=1
)
¶
Increment the line number and end line number of each node in the tree starting at node by n . This is useful to “move code” to a different location in a file.
ast.
copy_location
(
new_node
,
old_node
)
¶
Copy source location (
lineno
,
col_offset
,
end_lineno
,和
end_col_offset
) from
old_node
to
new_node
if possible, and return
new_node
.
ast.
iter_fields
(
node
)
¶
Yield a tuple of
(fieldname, value)
for each field in
node._fields
that is present on
node
.
ast.
iter_child_nodes
(
node
)
¶
Yield all direct child nodes of node , that is, all fields that are nodes and all items of fields that are lists of nodes.
ast.
walk
(
node
)
¶
Recursively yield all descendant nodes in the tree starting at node (including node itself), in no specified order. This is useful if you only want to modify nodes in place and don’t care about the context.
ast.
NodeVisitor
¶
A node visitor base class that walks the abstract syntax tree and calls a visitor function for every node found. This function may return a value which is forwarded by the
visit()
方法。
This class is meant to be subclassed, with the subclass adding visitor methods.
visit
(
node
)
¶
Visit a node. The default implementation calls the method called
self.visit_classname
where
classname
is the name of the node class, or
generic_visit()
if that method doesn’t exist.
generic_visit
(
node
)
¶
This visitor calls
visit()
on all children of the node.
Note that child nodes of nodes that have a custom visitor method won’t be visited unless the visitor calls
generic_visit()
or visits them itself.
不使用
NodeVisitor
if you want to apply changes to nodes during traversal. For this a special visitor exists (
NodeTransformer
) that allows modifications.
从 3.8 版起弃用:
方法
visit_Num()
,
visit_Str()
,
visit_Bytes()
,
visit_NameConstant()
and
visit_Ellipsis()
are deprecated now and will not be called in future Python versions. Add the
visit_Constant()
method to handle all constant nodes.
ast.
NodeTransformer
¶
A
NodeVisitor
subclass that walks the abstract syntax tree and allows modification of nodes.
NodeTransformer
will walk the AST and use the return value of the visitor methods to replace or remove the old node. If the return value of the visitor method is
None
, the node will be removed from its location, otherwise it is replaced with the return value. The return value may be the original node in which case no replacement takes place.
Here is an example transformer that rewrites all occurrences of name lookups (
foo
) to
data['foo']
:
class RewriteName(NodeTransformer):
def visit_Name(self, node):
return Subscript(
value=Name(id='data', ctx=Load()),
slice=Constant(value=node.id),
ctx=node.ctx
)
Keep in mind that if the node you’re operating on has child nodes you must either transform the child nodes yourself or call the
generic_visit()
method for the node first.
For nodes that were part of a collection of statements (that applies to all statement nodes), the visitor may also return a list of nodes rather than just a single node.
若
NodeTransformer
introduces new nodes (that weren’t part of original tree) without giving them location information (such as
lineno
),
fix_missing_locations()
should be called with the new sub-tree to recalculate the location information:
tree = ast.parse('foo', mode='eval')
new_tree = fix_missing_locations(RewriteName().visit(tree))
Usually you use the transformer like this:
node = YourTransformer().visit(node)
ast.
dump
(
node
,
annotate_fields=True
,
include_attributes=False
,
*
,
indent=None
)
¶
Return a formatted dump of the tree in node . This is mainly useful for debugging purposes. If annotate_fields is true (by default), the returned string will show the names and the values for fields. If annotate_fields is false, the result string will be more compact by omitting unambiguous field names. Attributes such as line numbers and column offsets are not dumped by default. If this is wanted, include_attributes can be set to true.
若
indent
is a non-negative integer or string, then the tree will be pretty-printed with that indent level. An indent level of 0, negative, or
""
将仅插入换行符。
None
(the default) selects the single line representation. Using a positive integer indent indents that many spaces per level. If
indent
是字符串 (譬如
"\t"
),使用该字符串缩进每个级别。
3.9 版改变: 添加 indent 选项。
The following flags may be passed to
compile()
in order to change effects on the compilation of a program:
ast.
PyCF_ALLOW_TOP_LEVEL_AWAIT
¶
Enables support for top-level
await
,
async for
,
async with
and async comprehensions.
3.8 版新增。
ast.
PyCF_ONLY_AST
¶
Generates and returns an abstract syntax tree instead of returning a compiled code object.
3.9 版新增。
ast
module can be executed as a script from the command line. It is as simple as:
python -m ast [-m <mode>] [-a] [infile]
The following options are accepted:
-h
,
--help
¶
Show the help message and exit.
-m
<mode>
¶
--mode
<mode>
¶
Specify what kind of code must be compiled, like the
mode
argument in
parse()
.
--no-type-comments
¶
Don’t parse type comments.
-a
,
--include-attributes
¶
Include attributes such as line numbers and column offsets.
若
infile
is specified its contents are parsed to AST and dumped to stdout. Otherwise, the content is read from stdin.
另请参阅
Green Tree Snakes , an external documentation resource, has good details on working with Python ASTs.
ASTTokens annotates Python ASTs with the positions of tokens and text in the source code that generated them. This is helpful for tools that make source code transformations.
leoAst.py unifies the token-based and parse-tree-based views of python programs by inserting two-way links between tokens and ast nodes.
LibCST parses code as a Concrete Syntax Tree that looks like an ast tree and keeps all formatting details. It’s useful for building automated refactoring (codemod) applications and linters.
Parso is a Python parser that supports error recovery and round-trip parsing for different Python versions (in multiple Python versions). Parso is also able to list multiple syntax errors in your python file.