ast --- 抽象構文木

ソースコード: Lib/ast.py


ast モジュールは、Python アプリケーションで Python の抽象構文木を処理しやすくするものです。抽象構文そのものは、Python のリリースごとに変化する可能性があります。このモジュールを使用すると、現在の文法をプログラム上で知る助けになるでしょう。

抽象構文木を作成するには、 ast.PyCF_ONLY_AST を組み込み関数 compile() のフラグとして渡すか、あるいはこのモジュールで提供されているヘルパー関数 parse() を使います。その結果は、 ast.AST を継承したクラスのオブジェクトのツリーとなります。抽象構文木は組み込み関数 compile() を使って Python コード・オブジェクトにコンパイルすることができます。

抽象文法 (Abstract Grammar)

抽象文法は、現在次のように定義されています:

-- 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)
}

Node クラス

class ast.AST

このクラスは全ての AST ノード・クラスの基底です。実際のノード・クラスは 後ほど 示す Parser/Python.asdl ファイルから派生したものです。これらのクラスは _ast C モジュールで定義され、 ast にもエクスポートし直されています。

抽象文法の左辺のシンボル一つずつにそれぞれ一つのクラスがあります (たとえば ast.stmtast.expr)。それに加えて、右辺のコンストラクタ一つずつにそれぞれ一つのクラスがあり、これらのクラスは左辺のツリーのクラスを継承しています。たとえば、 ast.BinOpast.expr から継承しています。代替を伴った生成規則 (production rules with alternatives) (別名 "sums") の場合、左辺は抽象クラスとなり、特定のコンストラクタ・ノードのインスタンスのみが作成されます。

_fields

各具象クラスは属性 _fields を持っており、すべての子ノードの名前をそこに保持しています。

具象クラスのインスタンスは、各子ノードに対してそれぞれひとつの属性を持っています。この属性は、文法で定義された型となります。たとえば ast.BinOp のインスタンスは left という属性を持っており、その型は ast.expr です。

これらの属性が、文法上 (クエスチョンマークを用いて) オプションであるとマークされている場合は、その値が None となることもあります。属性が0個以上の複数の値をとりうる場合 (アスタリスクでマークされている場合) は、値は Python のリストで表されます。全ての属性は AST を compile() でコンパイルする際には存在しなければならず、そして妥当な値でなければなりません。

lineno
col_offset
end_lineno
end_col_offset

Instances of ast.expr and ast.stmt subclasses have lineno, col_offset, end_lineno, and 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.

コンパイラは終了位置を必要としないことに注意してください。このため終了位置は省略可能です。終了位置を示すオフセットは最後のシンボルの 後の位置 になります。例えば一行で書かれた式のソースコードのセグメントは source_line[node.col_offset : node.end_col_offset] により取得できます。

クラス ast.T のコンストラクタは引数を次のように解析します:

  • 位置引数があるとすれば、 T._fields にあるのと同じだけの個数が無ければなりません。これらの引数はそこにある名前を持った属性として割り当てられます。

  • キーワード引数があるとすれば、それらはその名前の属性にその値を割り当てられます。

たとえば、 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

もしくはよりコンパクトにも書けます

node = ast.UnaryOp(ast.USub(), ast.Constant(5, lineno=0, col_offset=0),
                   lineno=0, col_offset=0)

バージョン 3.8 で変更: ast.Constant が全ての定数に使われるようになりました。

バージョン 3.9 で変更: 単純なインデックスはその値で表現され、幅を持つスライスはタプルで表現されます。

バージョン 3.8 で非推奨: 古いクラスである ast.Num, ast.Str, ast.Bytes, ast.NameConstant および ast.Ellipsis は現バージョンでは利用可能ですが、将来の Python リリースで削除される予定です。それまでは、これらのクラスをインスタンス化すると異なるクラスのインスタンスが返されます。

バージョン 3.9 で非推奨: 古いクラスである ast.Indexast.ExtSlice は現バージョンでは利用可能ですが、将来の Python リリースで削除される予定です。それまでは、これらのクラスをインスタンス化すると異なるクラスのインスタンスが返されます。

注釈

ここに示されている特定のノードクラスについての記述は、素晴らしい Green Tree Snakes プロジェクトとそのすべての貢献者の成果物をもとにしています。

リテラル

class ast.Constant(value)

定数です。 Constant リテラルの value 属性は定数値を表す Python オブジェクトを保持します。定数として表現される値は数値、文字列、または None のような単純な型のほかに、全ての要素が定数であるイミュータブルなコンテナ型 (tuples および frozensets) も設定可能です。

>>> print(ast.dump(ast.parse('123', mode='eval'), indent=4))
Expression(
    body=Constant(value=123))
class ast.FormattedValue(value, conversion, format_spec)

このノードは f-string における単一の書式指定置換フィールドを表現します。文字列が単一の置換フィールドしか持たず、他に何も含まない場合は、ノードは単独で存在できます。そうでない場合は JoinedStr の一部としてあらわれます。

  • value は式ツリーのノードのいずれか (リテラル、変数、関数呼び出しなど) です。

  • conversion は整数です:

    • -1: 書式指定なし

    • 115: !s 文字列書式指定

    • 114: !r repr 書式指定

    • 97: !a ascii 書式指定

  • format_spec は値の書式指定を表現する JoinedStr ノード、もしくは書式指定がない場合は None です。 conversionformat_spec を同時に設定することができます。

class ast.JoinedStr(values)

FormattedValue ノードと Constant ノードの集まりからなる f-string です。

>>> 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')]))]))
class ast.List(elts, ctx)
class ast.Tuple(elts, ctx)

リストまたはタプルをあらわします。 elts は内包する要素を表現するノードのリストを保持します。 ctx はコンテナが代入のターゲットである場合 (たとえば (x,y)=something のような場合) は Store であり、そうでない場合は 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()))
class ast.Set(elts)

集合 (set) をあらわします。 elts は集合の各要素を表現するノードのリストを保持します。

>>> 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)]))
class ast.Dict(keys, values)

辞書をあらわします。 keysvalues はそれぞれキーと値のノードのリスト を順序が一致した形で (それぞれ dictionary.keys()dictionary.values() を呼び出したときに返される順序で) 保持します。

辞書リテラルを使って辞書を展開した場合、展開された式ツリーにおいて辞書は values リストに入り、 keys の対応する位置には None が入ります。

>>> 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())]))

変数

class ast.Name(id, ctx)

変数名をあらわします。 id は変数名を文字列で保持し、 ctx は以下に示す型のいずれかです。

class ast.Load
class ast.Store
class ast.Del

変数の参照は変数の値をロードするか、新しい値を割り当てるか、または値を削除するために使うことができます。変数の参照はこれら3つの場合を区別するためのコンテキストによって与えられます。

>>> 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=[])
class ast.Starred(value, ctx)

*var 形式の変数の参照をあらわします。 value は変数、典型的には Name ノード、を保持します。この型は *args を伴う関数呼び出しノード Call を構築する際に使用します。

>>> 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=[])

式 (expression)

class ast.Expr(value)

関数呼び出しのような式がそれ自身で文となり、戻り値が使われないかまたは保存されないとき、その式はこのコンテナでラップされます。 value はこの節で説明する他のノード、 Constant ノード、 Name ノード、 Lambda ノード Yield ノードまたは YieldFrom ノードのいずれかを保持します。

>>> print(ast.dump(ast.parse('-a'), indent=4))
Module(
    body=[
        Expr(
            value=UnaryOp(
                op=USub(),
                operand=Name(id='a', ctx=Load())))],
    type_ignores=[])
class ast.UnaryOp(op, operand)

単項演算をあらわします。 op は演算子で、 operand は任意の式ツリーのノードです。

class ast.UAdd
class ast.USub
class ast.Not
class ast.Invert

単項演算の演算子をあらわします。 Not は論理否定キーワード not であり、 Invert はビット反転演算子 ~ です。

>>> print(ast.dump(ast.parse('not x', mode='eval'), indent=4))
Expression(
    body=UnaryOp(
        op=Not(),
        operand=Name(id='x', ctx=Load())))
class ast.BinOp(left, op, right)

(加算や減算のような) 二項演算をあらわします。 op は演算子、 leftright は任意の式ツリーのノードです。

>>> 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())))
class ast.Add
class ast.Sub
class ast.Mult
class ast.Div
class ast.FloorDiv
class ast.Mod
class ast.Pow
class ast.LShift
class ast.RShift
class ast.BitOr
class ast.BitXor
class ast.BitAnd
class ast.MatMult

二項演算の演算子をあらわします。

class ast.BoolOp(op, values)

'or' や 'and' のような論理演算をあらわします。 opOr または And です。 values は必要な値のリストです。 a or b or c のように同じ演算子を使う連続した演算は、複数の値を持った単一のノードとして表現されます。

not は単項演算 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())]))
class ast.And
class ast.Or

論理演算の演算子をあらわします。

class ast.Compare(left, ops, comparators)

2つ以上の値の比較をあらわします。 left 比較の中の最初の値、ops は演算子のリスト、 comparators は2つ目以降の値のリストです。

>>> 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)]))
class ast.Eq
class ast.NotEq
class ast.Lt
class ast.LtE
class ast.Gt
class ast.GtE
class ast.Is
class ast.IsNot
class ast.In
class ast.NotIn

比較演算の演算子をあらわします。

class ast.Call(func, args, keywords, starargs, kwargs)

関数呼び出しをあらわします。 func は関数で、多くの場合 Name または Attribute のオブジェクトです。 関数呼び出しの引数:

  • args は位置引数のリストを保持します。

  • keywordskeyword クラスのオブジェクトのリスト保持し、キーワード引数をあらわします。

Call ノードを生成するときに argskeywords は必須ですが、空のリストであってもかまいません。 starargskwargs はオプション引数です。

>>> 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()))]))
class ast.keyword(arg, value)

関数呼び出しまたはクラス定義のキーワード引数をあらわします。 arg はパラメータ名をあらわす文字列、 value は引数に渡す値をあらわすノードです。

class ast.IfExp(test, body, orelse)

a if b else c のような式をあらわします。各フィールドは単一のノードを保持します。以下の例では、3つの式ノードはすべて 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())))
class ast.Attribute(value, attr, ctx)

たとえば d.keys のような属性へのアクセスです。 value はノードで、典型的には Name です。 attr は属性名を与える生の文字列で、 ctx はその属性がどのように振る舞うかに応じて LoadStore または Del のいずれかです。

>>> print(ast.dump(ast.parse('snake.colour', mode='eval'), indent=4))
Expression(
    body=Attribute(
        value=Name(id='snake', ctx=Load()),
        attr='colour',
        ctx=Load()))
class ast.NamedExpr(target, value)

代入式です。この AST ノードは代入式演算子(ウォルラス演算子、または「セイウチ演算子」としても知られています)によって生成されます。第一引数が複数のノードであってもよい Assign ノードと異なり、このノードの場合は targetvalue の両方が単一のノードでなければなりません。

>>> print(ast.dump(ast.parse('(x := 4)', mode='eval'), indent=4))
Expression(
    body=NamedExpr(
        target=Name(id='x', ctx=Store()),
        value=Constant(value=4)))

配列要素の参照 (Subscripting)

class ast.Subscript(value, slice, ctx)

l[1] のような配列要素の参照をあらわします。 value は参照元のオブジェクトです (通常シーケンス型またはマッピング型)。 slice はインデックス、スライス、またはキーです。 Slice を含む Tuple でもかまいません。 ctx は要素の参照により実行されるアクションに応じて LoadStore または Del のいずれかです。

>>> 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()))
class ast.Slice(lower, upper, step)

基本的なスライス操作 (lower:upperlower:upper:step の形式) をあらわします。 Subscriptslice フィールドでの直接指定か、または 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()))

内包表記 (Comprehension)

class ast.ListComp(elt, generators)
class ast.SetComp(elt, generators)
class ast.GeneratorExp(elt, generators)
class ast.DictComp(key, value, generators)

リストや集合の内包表記、ジェネレータ、および辞書の内包表記です。 elt (または keyvalue) は各要素として評価される部品をあらわす単一のノードです。

generatorscomprehension ノードのリストです。

>>> 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)]))
class ast.comprehension(target, iter, ifs, is_async)

内包表記におけるひとつの for 節をあらわします。 target は各要素への参照です - 典型的には Name または Tuple ノードです。 iter はイテレートする対象のオブジェクトです。 ifs は条件節のリストです: 各 for 節は複数の ifs を持つことができます。

is_async は内包表記が非同期であることを示します (async forfor の代わりに使います)。値は整数です (0 または 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)]))

文 (Statements)

class ast.Assign(targets, value, type_comment)

代入です。 targets はノードのリスト、 value は単一のノードです。

targets の複数のノードは、それぞれに対して同じ値を代入することをあらわします。分割代入は targets 内に Tuple または List を置くことで表現されます。

type_comment

type_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=[])
class ast.AnnAssign(target, annotation, value, simple)

型アノテーションを伴う代入です。 target は単一のノードで、 Name, Attribute または Subscript のいずれかです。 annotationConstantName node のようなアノテーションです。 value はオプションで、代入する値を単一のノードであらわしたものです。 simple 真偽値と解釈される整数で、 targetName ノードが丸かっこに囲まれておらず、したがって式ではなく純粋な名前である場合に True を設定します。

>>> 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=[])
class ast.AugAssign(target, op, value)

a += 1 のような累積代入をあらわします。下記の例では、 target は (Store コンテキストを伴う) x のための Name ノード、 opAdd 演算子、そして value は定数1をあらわす Constant ノードです。

The 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=[])
class ast.Raise(exc, cause)

raise 文をあらわします。 exc は送出される例外オブジェクトで、通常は Call または Name、 もしくは単独の raise では None を指定します。 cause はオプションで、 raise x from yy にあたります。

>>> 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=[])
class ast.Assert(test, msg)

アサーションです。 testCompare ノードなどのような条件を保持します。 msg は失敗した時のメッセージを保持します。

>>> 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=[])
class ast.Delete(targets)

del 文をあらわします。 targetsName, Attribute, 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=[])
class ast.Pass

pass 文をあらわします。

>>> print(ast.dump(ast.parse('pass'), indent=4))
Module(
    body=[
        Pass()],
    type_ignores=[])

関数またはループの内部でのみ適用可能な他の文は、別のセクションで説明します。

インポート

class ast.Import(names)

インポート文です。 namesalias ノードのリストです。

>>> 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=[])
class ast.ImportFrom(module, names, level)

from x import y をあらわします。 module は 'from' でインポートする先頭がドットでないモジュール名をあらわす文字列か、または from . import foo のような構文の場合は None を指定します。 level は相対インポートのレベルを表す整数を保持します (0 は絶対インポートを意味します)。

>>> 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=[])
class ast.alias(name, asname)

いずれのパラメータも名前をあらわす生の文字列です。 asname は標準の名前を使う場合は None を指定できます。

>>> 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=[])

制御フロー

注釈

else 節のようなオプションの節が存在しない場合は、空のリストとして保存されます。

class ast.If(test, body, orelse)

if 文です。 testCompare ノードなどの単一のノードを保持します。 bodyorelse はそれぞれノードのリストを保持します。

elif 節は AST において固有の表現を持たず、先行する節をあらわすノードの orelse セクションに追加の If ノードとして現れます。

>>> 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=[])
class ast.For(target, iter, body, orelse, type_comment)

for ループです。 target はループが割り当てる単一または複数の変数を Name, Tuple または List のいずれかを単一のノードで保持します。 iter はループ対象の変数を、同じく単一のノードで保持します。 bodyorelse は実行するノードのリストを含んでいます。 orelse に含まれるノードは、ループが break 文によって中断せず、正常終了した場合に実行されます。

type_comment

type_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=[])
class ast.While(test, body, orelse)

while ループです。 testCompare のような条件をあらわすノードを保持します。

>> 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=[])
class ast.Break
class ast.Continue

break 文および 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=[])
class ast.Try(body, handlers, orelse, finalbody)

try ブロックです。 ExceptHandler ノードのリストである handlers を除き、全ての属性はそれぞれの節で実行するノードのリストです。

>>> 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=[])
class ast.ExceptHandler(type, name, body)

単一の except 節をあらわします。 type はこの節にマッチする例外のタイプで、典型的には Name ノードです (None を指定すると全ての例外をキャッチする except: 節をあらわします)。 name は例外オブジェクトを保持する変数の名前をあらわす生の文字列で、 as foo を持たない節の場合は None を指定します。 body はノードのリストです。

>>> 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=[])
class ast.With(items, body, type_comment)

with ブロックです。 itemswithitem ノードのリストで、コンテキストマネージャのリストをあらわします。また body はコンテキスト内にインデントされたブロックです。

type_comment

type_comment はコメントとして型アノテーションをあらわすオプション文字列です。

class ast.withitem(context_expr, optional_vars)

with ブロックにおける単一のコンテキストマネージャをあらわします。 context_expr はコンテキストマネージャで、しばしば Call ノードが設定されます。 optional_varsas foo に相当する Name, Tuple または List のいずれかのノードか、または、この部分が不要な場合は None を設定します。

>>> 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=[])

関数およびクラス定義

class ast.FunctionDef(name, args, body, decorator_list, returns, type_comment)

関数定義です。

  • name は関数名をあらわす生の文字列です。

  • args は引数をあらわす arguments ノードです。

  • body は関数の本体をあらわすノードのリストです。

  • decorator_list は関数に適用されるデコレータのリストで、外側のデコレータがリストの先頭に保存されます (すなわち、リストの先頭にあるデコレータが最後に適用されます)。

  • returns は戻り値に対する注釈です。

type_comment

type_comment はコメントとして型アノテーションをあらわすオプション文字列です。

class ast.Lambda(args, body)

lambda は式の中で使うことができる最小限の関数定義です。 FunctionDef ノードと異なり、 body は単一のノードとなります。

>>> 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=[])
class ast.arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults, kwarg, defaults)

関数の引数

  • posonlyargs, args および kwonlyargs はそれぞれ arg ノードのリストです。

  • varargkwarg はそれぞれ単一の arg ノードで、 *args, **kwargs パラメータに相当します。

  • kw_defaults はキーワード専用引数に対するデフォルト値のリストです。値が None の場合、対応する引数は必須となります。

  • defaults は位置引数として渡すことのできる引数に対するデフォルト値のリストです。デフォルト値の数nが位置引数の数より少ない場合、それらは最後のn個の引数に割り当てられます。

class ast.arg(arg, annotation, type_comment)

単一の引数をあらわします。 arg は引数名をあらわす生の文字列、 annotation は、 StrName ノードのような引数に対する注釈です。

type_comment

type_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=[])
class ast.Return(value)

return 文です。

>>> print(ast.dump(ast.parse('return 4'), indent=4))
Module(
    body=[
        Return(
            value=Constant(value=4))],
    type_ignores=[])
class ast.Yield(value)
class ast.YieldFrom(value)

yield または yield from 式をあらわします。これらは式なので、送り返される値が使われない場合は Expr ノードでラップされなければなりません。

>>> 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=[])
class ast.Global(names)
class ast.Nonlocal(names)

global および nonlocal 文です。 names は生の文字列のリストです。

>>> 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=[])
class ast.ClassDef(name, bases, keywords, starargs, kwargs, body, decorator_list)

クラス定義です。

  • name はクラス名をあらわす生の文字列です。

  • bases は明示的に指定された基底クラスをあらわすノードのリストです。

  • keywords is a list of keyword nodes, principally for 'metaclass'. Other keywords will be passed to the metaclass, as per PEP-3115.

  • starargskwargs は、関数呼び出しの場合と同様にそれぞれ単一のノードです。 starargs はベースクラスのリストと結合するために展開され、 kwargs はメタクラスに渡されます。

  • body はクラス定義に含まれるコードをあらわすノードのリストです。

  • decorator_list はノードのリストで、関数定義 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=[])

async と await

class ast.AsyncFunctionDef(name, args, body, decorator_list, returns, type_comment)

async def 形式の関数定義です。通常の関数定義 FunctionDef と同じフィールドを持ちます。

class ast.Await(value)

await 式をあらわします。 value は待ち受ける値です。 AsyncFunctionDef の本体 (body) の中でのみ有効です。

>>> 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=[])
class ast.AsyncFor(target, iter, body, orelse, type_comment)
class ast.AsyncWith(items, body, type_comment)

async for ループと async with コンテキストマネージャです。それぞれ For および With と同じフィールドを持ちます。 AsyncFunctionDef の本体 (body) の中でのみ有効です。

注釈

文字列が ast.parse() によってパースされたとき、戻り値のツリーに含まれる演算子ノード (ast.operator, ast.unaryop, ast.cmpop, ast.boolop および ast.expr_context のサブクラス) はシングルトンです。したがっていずれかの演算子ノードを変更すると、その変更は他の全ての同じ値 (たとえば ast.Add ノードを変更した場合はその他全ての ast.Add ノード) に反映されます。

ast ヘルパー

ノード・クラスの他に、 ast モジュールは以下のような抽象構文木をトラバースするためのユーティリティ関数やクラスも定義しています:

ast.parse(source, filename='<unknown>', mode='exec', *, type_comments=False, feature_version=None)

source を解析して AST ノードにします。compile(source, filename, mode, ast.PyCF_ONLY_AST) と等価です。

type_comments=True が与えられると、パーサは PEP 484 および PEP 526 で規定された型コメントをチェックし、返すように修正されます。これは ast.PyCF_TYPE_COMMENTS を追加したフラグを compile() に渡すことと等価です。パーサは不適切な場所に配置された型コメントに対してシンタックスエラーをレポートします。 このフラグがない場合、型コメントは無視されて AST ノードの type_comment フィールドは常に None になります。さらに、 # type: ignore コメントの位置は Moduletype_ignores 属性として返されます (それ以外の場合は常に空のリストになります)。

さらに mode'func_type' の場合、入力構文は、たとえば (str, int) -> List[str] のような PEP 484 の "シグネチャ型コメント (signature type comments)" に対応するように修正されます。

また、 feature_version(major, minor) のタプルに設定すると、パーサは指定された Python バージョンの文法で構文解析を試みます。今のところ major3 でなければなりません。たとえば、 feature_version=(3, 4) と設定すると asyncawait を変数名として使うことが可能になります。 サポートされている最低のバージョンは (3, 4); 最高のバージョンは sys.version_info[0:2] です。

If source contains a null character ('0'), ValueError is raised.

警告

Note that successfully parsing source code into an AST object doesn't guarantee that the source code provided is valid Python code that can be executed as the compilation step can raise further SyntaxError exceptions. For instance, the source return 42 generates a valid AST node for a return statement, but it cannot be compiled alone (it needs to be inside a function node).

In particular, ast.parse() won't do any scoping checks, which the compilation step does.

警告

十分に大きい文字列や複雑な文字列によって Python の抽象構文木コンパイラのスタックの深さの限界を越えることで、 Python インタプリタをクラッシュさせることができます。

バージョン 3.8 で変更: type_commentsmode='func_type'``feature_version``が追加されました。

ast.unparse(ast_obj)

ast.AST オブジェクトを逆に構文解析して、 ast.parse() が元の ast.AST と等価なオブジェクトを生成できるような文字列を生成します。

警告

生成されたコード文字列は、生成元のコードである ast.AST オブジェクトと必ずしも等価であるとは限りません (定数タプルや frozenset などに対するコンパイラ最適化なしのコードです)。

警告

非常に複雑な式を逆構文解析すると RecursionError となることがあります。

バージョン 3.9 で追加.

ast.literal_eval(node_or_string)

式ノードまたは Python のリテラルまたはコンテナのディスプレイ表現を表す文字列を安全に評価します。与えられる文字列またはノードは次のリテラルのみからなるものに限られます: 文字列、バイト列、数、タプル、リスト、辞書、集合、ブール値、 None

この関数は Python の式を含んだ信頼出来ない出どころからの文字列を、値自身を解析することなしに安全に評価するのに使えます。この関数は、例えば演算や添え字を含んだ任意の複雑な表現を評価するのには使えません。

警告

十分に大きい文字列や複雑な文字列によって Python の抽象構文木コンパイラのスタックの深さの限界を越えることで、 Python インタプリタをクラッシュさせることができます。

バージョン 3.2 で変更: バイト列リテラルと集合リテラルが受け取れるようになりました。

バージョン 3.9 で変更: 'set()' による空の集合の生成をサポートするようになりました。

ast.get_docstring(node, clean=True)

与えられた node (これは FunctionDef, AsyncFunctionDef, ClassDef, Module のいずれかのノードでなければなりません) のドキュメント文字列を返します。もしドキュメント文字列が無ければ None を返します。 clean が真ならば、ドキュメント文字列のインデントを inspect.cleandoc() を用いて一掃します。

バージョン 3.5 で変更: AsyncFunctionDef がサポートされました。

ast.get_source_segment(source, node, *, padded=False)

source のうちで node を生成したソースコードのセグメントを取得します。位置情報 (lineno, end_lineno, col_offset, または end_col_offset) が欠けている場合 None を返します。

paddedTrue の場合、複数行にわたる文の最初の行が元の位置に一致するように空白文字でパディングされます。

バージョン 3.8 で追加.

ast.fix_missing_locations(node)

compile() はノード・ツリーをコンパイルする際、 linenocol_offset 両属性をサポートする全てのノードに対しそれが存在するものと想定します。生成されたノードに対しこれらを埋めて回るのはどちらかというと退屈な作業なので、このヘルパーが再帰的に二つの属性がセットされていないものに親ノードと同じ値をセットしていきます。再帰の出発点が node です。

ast.increment_lineno(node, n=1)

node で始まるツリー内の各ノードの行番号と終了行番号を n ずつ増やします。これはファイルの中で別の場所に "コードを移動する" ときに便利です。

ast.copy_location(new_node, old_node)

ソースの場所 (lineno, col_offset, end_lineno, および end_col_offset) を old_node から new_node に可能ならばコピーし、 new_node を返します。

ast.iter_fields(node)

node にある node._fields のそれぞれのフィールドを (フィールド名, 値) のタプルとして yield します。

ast.iter_child_nodes(node)

node の直接の子ノード全てを yield します。すなわち、yield されるのは、ノードであるような全てのフィールドおよびノードのリストであるようなフィールドの全てのアイテムです。

ast.walk(node)

node の全ての子孫ノード(node 自体を含む)を再帰的に yield します。順番は決められていません。この関数はノードをその場で変更するだけで文脈を気にしないような場合に便利です。

class ast.NodeVisitor

抽象構文木を渡り歩いてビジター関数を見つけたノードごとに呼び出すノード・ビジターの基底クラスです。この関数は visit() メソッドに送られる値を返してもかまいません。

このクラスはビジター・メソッドを付け加えたサブクラスを派生させることを意図しています。

visit(node)

ノードを訪れます。デフォルトの実装では self.visit_classname というメソッド (ここで classname はノードのクラス名です) を呼び出すか、そのメソッドがなければ generic_visit() を呼び出します。

generic_visit(node)

このビジターはノードの全ての子について visit() を呼び出します。

注意して欲しいのは、専用のビジター・メソッドを具えたノードの子ノードは、このビジターが generic_visit() を呼び出すかそれ自身で子ノードを訪れない限り訪れられないということです。

トラバースの途中でノードを変化させたいならば NodeVisitor を使ってはいけません。そうした目的のために変更を許す特別なビジター (NodeTransformer) があります。

バージョン 3.8 で非推奨: visit_Num(), visit_Str(), visit_Bytes(), visit_NameConstant() および visit_Ellipsis() の各メソッドは非推奨です。また将来の Python バージョンでは呼び出されなくなります。全ての定数ノードを扱うには visit_Constant() を追加してください。

class ast.NodeTransformer

NodeVisitor のサブクラスで抽象構文木を渡り歩きながらノードを変更することを許すものです。

NodeTransformer は抽象構文木(AST)を渡り歩き、ビジター・メソッドの戻り値を使って古いノードを置き換えたり削除したりします。ビジター・メソッドの戻り値が None ならば、ノードはその場から取り去られ、そうでなければ戻り値で置き換えられます。置き換えない場合は戻り値が元のノードそのものであってもかまいません。

それでは例を示しましょう。Name (たとえば foo) を見つけるたび全て data['foo'] に書き換える変換器 (transformer) です:

class RewriteName(NodeTransformer):

    def visit_Name(self, node):
        return Subscript(
            value=Name(id='data', ctx=Load()),
            slice=Constant(value=node.id),
            ctx=node.ctx
        )

操作しようとしているノードが子ノードを持つならば、その子ノードの変形も自分で行うか、またはそのノードに対し最初に generic_visit() メソッドを呼び出すか、それを行うのはあなたの責任だということを肝に銘じましょう。

文のコレクションであるようなノード (全ての文のノードが当てはまります) に対して、このビジターは単独のノードではなくノードのリストを返すかもしれません。

NodeTransformer が(たとえば、 lineno のような)位置情報を与えずに(元の木の一部ではなく)新しいノードを導入する場合、 fix_missing_locations() を新しいサブツリーで呼び出して、位置情報を再計算する必要があります。

tree = ast.parse('foo', mode='eval')
new_tree = fix_missing_locations(RewriteName().visit(tree))

たいてい、変換器の使い方は次のようになります:

node = YourTransformer().visit(node)
ast.dump(node, annotate_fields=True, include_attributes=False, *, indent=None)

node 内のツリーのフォーマットされたダンプを返します。主な使い道はデバッグです。 annotate_fields が(デフォルトで)trueの場合、返される文字列はフィールドの名前と値を示します。 annotate_fields がfalseの場合、あいまいさのないフィールド名を省略することにより、結果文字列はよりコンパクトになります。行番号や列オフセットのような属性はデフォルトではダンプされません。これがほ欲しければ、 include_attributes をtrueにセットすることができます。

indent が非負の整数または文字列の場合、ツリーは指定されたインデントレベルで整形されて出力されます (pretty-printed)。インデントレベルがゼロ、負の数、または "" の場合は改行だけを挿入します。 None (デフォルト値) は単一行での表記になります。正の整数を指定すると各インデントレベルでその数だけの空白でインデントされます。 indent が文字列 ("\t" など) の場合、その文字列が各レベルのインデントに使われます。

バージョン 3.9 で変更: indent オプションを追加しました。

コンパイラフラグ

以下のフラグはプログラムのコンパイルにおける効果を変更するために compile() に渡すことができます:

ast.PyCF_ALLOW_TOP_LEVEL_AWAIT

トップレベルの await, async for, async with および async 内包表記のサポートを有効化します。

バージョン 3.8 で追加.

ast.PyCF_ONLY_AST

コンパイルされたコードオブジェクトの代わりに抽象構文木を生成して返します。

ast.PyCF_TYPE_COMMENTS

PEP 484 および PEP 526 形式の型コメント (# type: <type>, # type: ignore <stuff>) のサポートを有効化します。

バージョン 3.8 で追加.

コマンドラインからの使用

バージョン 3.9 で追加.

ast モジュールはコマンドラインからスクリプトとして実行することができます。実行方法は単純です:

python -m ast [-m <mode>] [-a] [infile]

以下のオプションが使用できます:

-h, --help

ヘルプメッセージを表示して終了します。

-m <mode>
--mode <mode>

parse() 関数の mode 引数と同様、コンパイルするコードの種類を指定します。

--no-type-comments

型コメントをパースしません。

-a, --include-attributes

行番号や列オフセットなどの属性を含めます。

-i <indent>
--indent <indent>

AST におけるノードのインデント (空白の数) です。

infile を指定するとその内容が AST にパースされて標準出力に出力されます。そうでない場合は標準入力から入力を読み込みます。

参考

外部ドキュメント Green Tree Snakes には Python AST についての詳細が書かれています。

ASTTokens は Python AST を、生成元のソースコードのトークン位置やテキストで注解します。これはソースコード変換を行うツールで有用です。

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 はコードを ast ツリーに似た構文木 (Concrete Syntax Tree) にパースし、かつ全ての書式設定の詳細を保持します。これは自動リファクタリングアプリケーション (codemod) やリンタを作成する際に有用です。

Parso はエラーリカバリや異なる Python バージョン (複数の Python バージョン) での復元可能なパース (round-trip parsing) をサポートします。また、 Parso は Python ファイル内の複数の文法エラーをリストすることもできます。