コードオブジェクト
******************

コードオブジェクト(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 が変更されるまでは
   利用できます。
