symtable --- コンパイラーの記号表へのアクセス

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


記号表は、バイトコードを生成する直前にコンパイラーが AST から生成します。 コード内のすべての識別子のスコープを決める役割を担います。 symtable はこれらの記号表を調べるためのインターフェースを提供します。

記号表の生成

symtable.symtable(code, filename, compile_type, *, module=None)

Python ソース code のトップレベルの SymbolTable を返します。 filename はコードを含むファイルの名前です。 compile_type は compile() の mode 引数と同様です。 省略可能な module 引数はモジュール名を指定します。 構文警告をモジュール名によって曖昧さなく フィルター するために必要です。

Added in version 3.15: module 引数が追加されました。

記号表の検査

class symtable.SymbolTableType

SymbolTable オブジェクトの種類を示す列挙型です。

MODULE = "module"

モジュールの記号表に使われます。

FUNCTION = "function"

関数の記号表に使われます。

CLASS = "class"

クラスの記号表に使われます。

次のメンバーは、アノテーションスコープ の種類を表します。

ANNOTATION = "annotation"

Used for annotations if from __future__ import annotations is active.

TYPE_ALIAS = "type alias"

type 構文の記号表に使われます。

TYPE_PARAMETERS = "type parameters"

ジェネリック関数 または ジェネリッククラス の記号表に使われます。

TYPE_VARIABLE = "type variable"

型変数、つまり TypeVar、TypeVarTuple、ParamSpec のいずれかのオブジェクト 1 つについて、その上限境界、制約タプル、デフォルト値の記号表に使われます (後ろの 2 つは上限境界や制約タプルをサポートしません)。

Added in version 3.13.

class symtable.SymbolTable

ブロックに対する名前空間の記号表。コンストラクタはパブリックではありません。

get_type()

記号表の種類を返します。 戻り値は SymbolTableType 列挙型のメンバーです。

バージョン 3.12 で変更: 戻り値として 'annotation'、'TypeVar bound'、'type alias'、'type parameter' が追加されました。

バージョン 3.13 で変更: 戻り値が SymbolTableType 列挙型のメンバーになりました。

返される文字列の具体的な値は将来変わる可能性があるため、文字列を直接書くのではなく SymbolTableType のメンバーを使うことを推奨します。

get_id()

記号表の識別子を返します。

get_name()

記号表の名前を返します。 クラスの記号表ならクラス名、関数の記号表なら関数名、グローバルな記号表 (get_type() が 'module' を返すもの) なら 'top' です。 ジェネリッククラス、関数、型エイリアスで使う型パラメータースコープの場合は、対応するクラス、関数、型エイリアスの名前です。 型エイリアススコープの場合は型エイリアスの名前です。 TypeVar の上限境界スコープの場合は、その TypeVar の名前です。

get_lineno()

この記号表に対応するブロックの一行目の行番号を返します。

is_optimized()

この記号表に含まれるローカル変数が最適化できるならば True を返します。

is_nested()

ブロックが入れ子のクラスまたは関数のとき True を返します。

has_children()

ブロックが入れ子の名前空間を含んでいるならば True を返します。入れ子の名前空間は get_children() で得られます。

get_identifiers()

記号表内の記号の名前を含むビューオブジェクトを返します。 ビューオブジェクトのドキュメント を参照してください。

lookup(name)

記号表から名前 name を見つけ出して Symbol インスタンスとして返します。

get_symbols()

記号表中の名前を表す Symbol インスタンスのリストを返します。

get_children()

入れ子になった記号表のリストを返します。

class symtable.Function

関数またはメソッドの名前空間です。 このクラスは SymbolTable を継承します。

get_parameters()

この関数の引数名からなるタプルを返します。

get_locals()

この関数のローカル変数の名前からなるタプルを返します。

get_globals()

この関数のグローバル変数の名前からなるタプルを返します。

get_nonlocals()

この関数内で明示的に nonlocal と宣言された名前のタプルを返します。

get_frees()

この関数内の 自由 (クロージャー) 変数 の名前のタプルを返します。

get_cells()

この記号表内の セル変数 の名前のタプルを返します。

Added in version 3.15.

class symtable.Class

クラスの名前空間です。 このクラスは SymbolTable を継承します。

get_methods()

クラス内で宣言された、メソッドに相当する関数の名前のタプルを返します。

ここで「メソッド」とは、クラス本体で def または async def によって定義された すべての 関数を指します。

より深いスコープ (内部クラスなど) で定義された関数は、get_methods() の結果には含まれません。

例えば:

>>> import symtable
>>> st = symtable.symtable('''
... def outer(): pass
...
... class A:
...    def f():
...        def w(): pass
...
...    def g(self): pass
...
...    @classmethod
...    async def h(cls): pass
...
...    global outer
...    def outer(self): pass
... ''', 'test', 'exec')
>>> class_A = st.get_children()[2]
>>> class_A.get_methods()
('f', 'g', 'h')

A().f() は実行時に TypeError を送出しますが、A.f はそれでもメソッドに相当する関数とみなされます。

バージョン 3.14 で非推奨、バージョン 3.16 で削除予定.

class symtable.Symbol

SymbolTable のエントリーでソースの識別子に対応するものです。コンストラクタはパブリックではありません。

get_name()

記号の名前を返します。

is_referenced()

記号がそのブロックの中で使われていれば True を返します。

is_imported()

記号が import 文で作られたものならば True を返します。

is_parameter()

記号がパラメータならば True を返します。

is_type_parameter()

記号が型パラメーターであれば True を返します。

Added in version 3.14.

is_global()

記号がグローバルならば True を返します。

is_nonlocal()

記号が非ローカルならば True を返します。

is_declared_global()

記号が global 文によってグローバルであると宣言されているなら True を返します。

is_local()

記号がそのブロックに対してローカルならば True を返します。

is_annotated()

記号が注釈付きならば True を返します。

Added in version 3.6.

is_free()

記号がそのブロックの中で参照されていて、しかし代入は行われないならば True を返します。

is_cell()

入れ子のブロックで記号が参照され、代入はされていない場合に True を返します。

Added in version 3.15.

is_free_class()

クラススコープの記号がメソッドから見て自由変数である場合、True を返します。

次に示す例について考えてみてください。:

def f():
    x = 1  # 関数スコープ
    class C:
        x = 2  # クラススコープ
        def method(self):
            return x

この例では、クラススコープの記号 x は C.method から見て自由変数とみなされます。 そのため、C.method は実行時に 2 ではなく 1 を返せます。

Added in version 3.14.

is_assigned()

記号がそのブロックの中で代入されているならば True を返します。

is_comp_iter()

記号が内包表記の反復変数であれば True を返します。

Added in version 3.14.

is_comp_cell()

記号がインライン化された内包表記のセルであれば True を返します。

Added in version 3.14.

is_namespace()

名前の束縛が新たな名前空間を導入するならば True を返します。

名前が関数または class 文のターゲットとして使われるならば、真です。

例えば:

>>> table = symtable.symtable("def some_func(): pass", "string", "exec")
>>> table.lookup("some_func").is_namespace()
True

一つの名前が複数のオブジェクトに束縛されうることに注意しましょう。結果が True であったとしても、その名前は他のオブジェクトにも束縛されるかもしれず、それがたとえば整数やリストであれば、そこでは新たな名前空間は導入されません。

get_namespaces()

この名前に束縛された名前空間のリストを返します。

get_namespace()

この名前に束縛された名前空間を返します。この名前に束縛された名前空間が複数あるか一つもないなら ValueError が送出されます。

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

Added in version 3.13.

symtable モジュールはコマンドラインからスクリプトとして実行できます。

python -m symtable [infile...]

指定した Python ソースファイルの記号表を生成し、標準出力に書き出します。 入力ファイルを指定しない場合は、標準入力から内容を読み込みます。