コードオブジェクト

コードオブジェクト(Code objects)は CPython 実装の低レベルな詳細部分です。各オブジェクトは関数に束縛されていない実行可能コードの塊を表現しています。

type PyCodeObject

コードオブジェクトを表現するために利用されるC構造体。この型のフィールドは何時でも変更され得ます。

PyTypeObject PyCode_Type

Python の コードオブジェクト を表す PyTypeObject のインスタンスです。

int PyCode_Check(PyObject *co)

co が コードオブジェクト の場合に真を返します。 この関数は常に成功します。

Py_ssize_t PyCode_GetNumFree(PyCodeObject *co)

コードオブジェクト内の 自由変数 (クロージャ変数) の数を返します。

int PyUnstable_Code_GetFirstFree(PyCodeObject *co)
これは Unstable APIです。マイナーリリースで予告なく変更されることがあります。

コードオブジェクト内の最初の 自由変数 (クロージャ変数) の位置を返します。

バージョン 3.13 で変更: 不安定な C API の一部として PyCode_GetFirstFree から名前を変更しました。 古い名前は非推奨ですが、シグネチャが再び変更されるまでは利用できます。

PyCodeObject *PyUnstable_Code_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
これは Unstable APIです。マイナーリリースで予告なく変更されることがあります。

新しいコードオブジェクトを返します。 フレームの作成にダミーのコードオブジェクトが必要な場合は、代わりに PyCode_NewEmpty() を使ってください。

バイトコードの定義は頻繁に変わるため、PyUnstable_Code_New() を直接呼び出すと、特定の Python バージョンに依存することがあります。

この関数の多数の引数は複雑に依存し合っているため、値を少し変えるだけで誤った実行や VM のクラッシュにつながりやすくなっています。 十分に注意して使ってください。

バージョン 3.11 で変更: qualname と exceptiontable 引数を追加しました。

バージョン 3.12 で変更: 不安定な C API の一部として PyCode_New から名前を変更しました。 古い名前は非推奨ですが、シグネチャが再び変更されるまでは利用できます。

PyCodeObject *PyUnstable_Code_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
これは Unstable APIです。マイナーリリースで予告なく変更されることがあります。

PyUnstable_Code_New() と同様ですが、位置専用引数のための posonlyargcount 引数が追加されています。 PyUnstable_Code_New と同じ注意事項が当てはまります。

Added in version 3.8: PyCode_NewWithPosOnlyArgs として追加。

バージョン 3.11 で変更: qualname と exceptiontable 引数を追加しました。

バージョン 3.12 で変更: PyUnstable_Code_NewWithPosOnlyArgs に名前を変更しました。 古い名前は非推奨ですが、シグネチャが再び変更されるまでは利用できます。

PyCodeObject *PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
戻り値: 新しい参照。

指定されたファイル名、関数名、開始行番号を持つ新しい空のコードオブジェクトを返します。 このコードオブジェクトを実行すると Exception を送出します。

int PyCode_Addr2Line(PyCodeObject *co, int byte_offset)

byte_offset の位置かそれ以前で始まり、その位置より後で終わる命令の行番号を返します。 コードオブジェクト内の命令数に対して O(N) となることがあるため、コードオブジェクト内のすべての行番号を順に調べる用途には効率的ではありません。

フレームの行番号だけが必要なら、代わりに PyFrame_GetLineNumber() を使ってください。

int PyCode_Addr2Location(PyObject *co, int byte_offset, int *start_line, int *start_column, int *end_line, int *end_column)

渡された int ポインタの参照先に、byte_offset にある命令のソースコード上の行番号と列番号を設定します。 情報がない項目には 0 を設定します。

成功した場合は 1 を返し、それ以外の場合は 0 を返します。

Added in version 3.11.

PyObject *PyCode_GetCode(PyCodeObject *co)

Python コード getattr(co, 'co_code') と同等です。 コードオブジェクト内のバイトコードを表す PyBytesObject への強参照を返します。 エラーの場合は例外を送出し、NULL を返します。

この PyBytesObject は、インタープリタが必要に応じて作成する場合があり、CPython が実際に実行するバイトコードを表すとは限りません。 この関数の主な用途はデバッガとプロファイラです。

Added in version 3.11.

PyObject *PyCode_GetVarnames(PyCodeObject *co)

Python コード getattr(co, 'co_varnames') と同等です。 ローカル変数の名前を含む PyTupleObject への新しい参照を返します。 エラーの場合は例外を送出し、NULL を返します。

Added in version 3.11.

PyObject *PyCode_GetCellvars(PyCodeObject *co)

Python コード getattr(co, 'co_cellvars') と同等です。 ネストした関数から参照されるローカル変数の名前を含む PyTupleObject への新しい参照を返します。 エラーの場合は例外を送出し、NULL を返します。

Added in version 3.11.

PyObject *PyCode_GetFreevars(PyCodeObject *co)

Python コード getattr(co, 'co_freevars') と同等です。 自由変数 (クロージャ変数) の名前を含む PyTupleObject への新しい参照を返します。 エラーの場合は例外を送出し、NULL を返します。

Added in version 3.11.

int PyCode_AddWatcher(PyCode_WatchCallback callback)

現在のインタープリタのコードオブジェクトウォッチャーとして callback を登録します。 PyCode_ClearWatcher() に渡せる ID を返します。 エラーの場合 (例えば利用可能なウォッチャー ID がない場合) は、例外を設定して -1 を返します。

Added in version 3.12.

int PyCode_ClearWatcher(int watcher_id)

現在のインタープリタについて、PyCode_AddWatcher() が以前返した watcher_id で識別されるウォッチャーを解除します。 成功した場合は 0 を返します。 エラーの場合 (例えば指定した watcher_id が登録されていない場合) は、例外を設定して -1 を返します。

Added in version 3.12.

type PyCodeEvent

コードオブジェクトウォッチャーで発生し得るイベントの列挙型: - PY_CODE_EVENT_CREATE - PY_CODE_EVENT_DESTROY

Added in version 3.12.

PY_FOREACH_CODE_EVENT(V)

PyCodeEvent 定数の各接尾辞にマクロ V を適用します。 現在は V(CREATE) V(DESTROY) に展開されます。 マクロ V は一つのイベント名を受け取り、展開結果の間に必要な区切り記号を補う必要があります。

typedef int (*PyCode_WatchCallback)(PyCodeEvent event, PyCodeObject *co)

コードオブジェクトウォッチャーのコールバック関数の型。

event が PY_CODE_EVENT_CREATE の場合、コールバックは co の初期化がすべて完了した後で呼び出されます。 それ以外の場合は co を破棄する前に呼び出されるので、破棄前の状態を調べられます。

event が PY_CODE_EVENT_DESTROY の場合、コールバック内で破棄されようとしているコードオブジェクトへの参照を取得すると、そのオブジェクトが復活し、この時点での解放を防ぎます。 復活したオブジェクトが後で破棄されるときは、その時点で有効なウォッチャーのコールバックが再び呼び出されます。

この API の利用者は、ランタイム内部の実装の詳細に依存してはいけません。 例えばコードオブジェクトの作成や破棄の正確な順序とタイミングなどが該当しますが、これらに限りません。 こうした詳細の変更によって、コールバックが呼び出されるかどうかも含めてウォッチャーから観測できる違いが生じることはありますが、実行される Python コードの意味は変わりません。

コールバックが例外を設定した場合は -1 を返す必要があります。 その例外は、PyErr_WriteUnraisable() を使って送出できない例外として表示されます。 それ以外の場合は 0 を返してください。

コールバックに入る時点で、すでに処理待ちの例外が設定されている場合があります。 その場合、コールバックは同じ例外を設定したまま 0 を返すべきです。 そのため、例外を設定し得る別の API を呼び出す場合は、まず例外の状態を保存してクリアし、戻る前に復元する必要があります。

Added in version 3.12.

PyObject *PyCode_Optimize(PyObject *code, PyObject *consts, PyObject *names, PyObject *lnotab_obj)

何も行わない関数です。

Python 3.10 より前では、この関数はコードオブジェクトに基本的な最適化を行っていました。

バージョン 3.10 で変更: この関数は何も行わなくなりました。

バージョン 3.13 で ソフト非推奨 <Soft deprecated>.

コードオブジェクトのフラグ

コードオブジェクトはフラグのビットフィールドを持ちます。 Python 属性 co_flags として (例えば PyObject_GetAttrString() で) 取得でき、PyUnstable_Code_New() などの関数の flags 引数で設定できます。

名前が CO_FUTURE_ で始まるフラグは、通常 future 文 で選択する機能に対応します。 これらは PyCompilerFlags.cf_flags で使えます。 現在の Python では、多くの CO_FUTURE_ フラグに対応する機能が必須となっており、フラグを設定しても効果はありません。

以下のフラグを利用できます。 意味については、対応する Python 側のフラグのドキュメントへのリンクを参照してください。

フラグ

意味

CO_OPTIMIZED

inspect.CO_OPTIMIZED

CO_NEWLOCALS

inspect.CO_NEWLOCALS

CO_VARARGS

inspect.CO_VARARGS

CO_VARKEYWORDS

inspect.CO_VARKEYWORDS

CO_NESTED

inspect.CO_NESTED

CO_GENERATOR

inspect.CO_GENERATOR

CO_COROUTINE

inspect.CO_COROUTINE

CO_ITERABLE_COROUTINE

inspect.CO_ITERABLE_COROUTINE

CO_ASYNC_GENERATOR

inspect.CO_ASYNC_GENERATOR

CO_HAS_DOCSTRING

inspect.CO_HAS_DOCSTRING

CO_METHOD

inspect.CO_METHOD

CO_FUTURE_DIVISION

効果なし (__future__.division)

CO_FUTURE_ABSOLUTE_IMPORT

効果なし (__future__.absolute_import)

CO_FUTURE_WITH_STATEMENT

効果なし (__future__.with_statement)

CO_FUTURE_PRINT_FUNCTION

効果なし (__future__.print_function)

CO_FUTURE_UNICODE_LITERALS

効果なし (__future__.unicode_literals)

CO_FUTURE_GENERATOR_STOP

効果なし (__future__.generator_stop)

CO_FUTURE_ANNOTATIONS

__future__.annotations

追加情報

外部の JIT コンパイラなど、フレーム評価の低レベルな拡張をサポートするため、コードオブジェクトには任意の追加データを付加できます。

これらの関数は不安定な C API の階層に属します。 この機能は CPython の実装の詳細であり、API は非推奨の警告なしに変更される可能性があります。

Py_ssize_t PyUnstable_Eval_RequestCodeExtraIndex(freefunc free)
これは Unstable APIです。マイナーリリースで予告なく変更されることがあります。

コードオブジェクトにデータを追加するための、新しい不透明なインデックス値を返します。

You generally call this function once (per interpreter) and use the result with PyCode_GetExtra and PyCode_SetExtra to manipulate data on individual code objects.

free が NULL でない場合、コードオブジェクトの解放時に、その新しいインデックスに格納されている非 NULL のデータに対して free を呼び出します。 PyObject を格納する場合は Py_DecRef() を使ってください。

Added in version 3.6: _PyEval_RequestCodeExtraIndex として追加。

バージョン 3.12 で変更: PyUnstable_Eval_RequestCodeExtraIndex に名前を変更しました。 古いプライベートな名前は非推奨ですが、API が変更されるまでは利用できます。

int PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
これは Unstable APIです。マイナーリリースで予告なく変更されることがあります。

指定されたインデックスに格納された追加データを extra に設定します。 成功した場合は 0 を返します。 失敗した場合は例外を設定して -1 を返します。

そのインデックスにデータが設定されていない場合は、extra を NULL に設定し、例外を設定せずに 0 を返します。

Added in version 3.6: _PyCode_GetExtra として追加。

バージョン 3.12 で変更: PyUnstable_Code_GetExtra に名前を変更しました。 古いプライベートな名前は非推奨ですが、API が変更されるまでは利用できます。

int PyUnstable_Code_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
これは Unstable APIです。マイナーリリースで予告なく変更されることがあります。

指定されたインデックスに格納する追加データを extra に設定します。 成功した場合は 0 を返します。 失敗した場合は例外を設定して -1 を返します。

Added in version 3.6: _PyCode_SetExtra として追加。

バージョン 3.12 で変更: PyUnstable_Code_SetExtra に名前を変更しました。 古いプライベートな名前は非推奨ですが、API が変更されるまでは利用できます。