定義用スロット¶
C API で モジュールオブジェクト や クラス を定義するには、スロット の配列を使えます。 スロットは基本的にはキーと値の組で、作成するオブジェクトの機能を記述します。 これにより、定義用のデータと実行時の構造体を切り離し、CPython や他の Python C API 実装が後方互換性を壊さずに構造体を変更できるようになります。
この節ではスロット全般を説明します。 オブジェクト固有の動作やスロットの値については、スロットを適用する関数の説明を参照してください。
型については
PyType_FromSlots()。モジュールについては
PyModule_FromSlotsAndSpec()と 拡張モジュールのエクスポートフック。
スロットを適用する関数に渡すとき、その関数はスロット配列も、配列が指すデータも (再帰的にたどった先を含めて) 変更しません。
関数が完了した後は、PySlot_STATIC と明示されたデータを除き、呼び出し側は配列とその参照先のデータを (再帰的にたどった先を含めて) 変更または解放できます。
別途記載されていない限り、同じ ID (sl_id) のスロットを 1 つのスロット配列に複数含めてはいけません。
Added in version 3.15: スロット配列は、従来のオブジェクト定義方法を一般化したものです。
従来は、型には PyType_Spec と PyType_Slot、モジュールには PyModuleDef と PyModuleDef_Slot を使っていました。
従来の API は 緩やかに非推奨 となっていますが、削除する予定はありません。
スロット配列のエントリーには次の構造体を使います。
-
type PySlot¶
- 次に属します: Stable ABI (すべてのメンバーを含む) (バージョン 3.15 より).
スロット配列のエントリーです。 次のように定義されています。
typedef struct { uint16_t sl_id; uint16_t sl_flags; union { uint32_t sl_reserved; // 0 でなければならない }; union { void *sl_ptr; void (*sl_func)(void); Py_ssize_t sl_size; int64_t sl_int64; uint64_t sl_uint64; }; } PySlot;
-
uint16_t sl_id¶
次の中から選ぶスロット ID。
後述の 共通のスロット ID に記載された
Py_slot_*の値。モジュールの定義 に記載された、モジュール用の
Py_mod_*の値。型のスロット ID に記載された、型用の値。
sl_idがゼロ (Py_slot_end) のエントリーは、スロット配列の終端を示します。
-
void *sl_ptr¶
-
void (*sl_func)(void)¶
-
Py_ssize_t sl_size¶
-
int64_t sl_int64¶
-
uint64_t sl_uint64¶
スロットのデータです。 これらのメンバーは無名共用体に含まれており、使うメンバーはスロット ID が要求するデータ型によって決まります。 それぞれデータポインタ、関数ポインタ、サイズ、符号付き整数、符号なし整数です。
個別のスロット ID の説明に別途記載されていない限り、ポインタ (
sl_ptrとsl_func) は NULL にできません。
-
uint16_t sl_flags¶
以下のフラグを 0 個以上、ビット OR で組み合わせた値。
-
PySlot_STATIC¶
- 次に属します: Stable ABI (バージョン 3.15 より).
スロットが指すすべてのデータが静的に割り当てられており、不変であることを示します。 このため、インタープリタは情報をコピーする必要がありません。
関数ポインタでは、このフラグが暗黙に指定されます。
このフラグは、スロットが「間接的に」指すデータにも適用されます。 ただし、
Py_slot_subslotsでネストしたスロットは例外で、それぞれ独自のPySlot_STATICフラグを持てます。 例えば、PyMemberDef構造体の配列を指すPy_tp_membersスロットに適用した場合、配列全体と、各要素の名前およびドキュメント文字列は、静的に割り当てられた不変のデータでなければなりません。
-
PySlot_INTPTR¶
- 次に属します: Stable ABI (バージョン 3.15 より).
データは
sl_ptrに格納され、CPython が適切な型にキャストします。このフラグは、従来の
PyType_Slot構造体やPyModuleDef_Slot構造体からの移行を簡単にします。
-
PySlot_OPTIONAL¶
- 次に属します: Stable ABI (バージョン 3.15 より).
スロット ID が未知の場合、インタープリタは失敗する代わりにそのスロットを無視します。
例えば、Python 3.16 で新しいスロット ID を使う機能が追加された場合、対応するスロットに
PySlot_OPTIONALを指定すれば、Python 3.15 ではそのスロットを無視できます。この「任意指定」は、未知のスロット ID にだけ適用される点に注意してください。 既知のスロットの無効な値が、このフラグによって無視されることはありません。
-
PySlot_STATIC¶
Added in version 3.15.
-
uint16_t sl_id¶
便利なマクロ¶
-
PySlot_DATA(name, value)¶
-
PySlot_FUNC(name, value)¶
-
PySlot_SIZE(name, value)¶
-
PySlot_INT64(name, value)¶
-
PySlot_UINT64(name, value)¶
-
PySlot_STATIC_DATA(name, value)¶
- This macro is available when compiling for the Stable ABI (バージョン 3.15 より).
sl_idと特定の共用体メンバーを設定したPySlot構造体を定義するための便利なマクロです。PySlot_STATIC_DATAはPySlot_STATICフラグを設定し、他のマクロはフラグを設定しません。これらのマクロは C 言語の機能である 指示付き初期化子 を使います。 C++ でこの機能が追加されたのは 2020 年版の標準です。 C++11 以前との互換性が必要な場合は、代わりに
PySlot_PTRを使ってください。次のように定義されています。
#define PySlot_DATA(NAME, VALUE) \ {.sl_id=NAME, .sl_ptr=(void*)(VALUE)} #define PySlot_FUNC(NAME, VALUE) \ {.sl_id=NAME, .sl_func=(VALUE)} #define PySlot_SIZE(NAME, VALUE) \ {.sl_id=NAME, .sl_size=(VALUE)} #define PySlot_INT64(NAME, VALUE) \ {.sl_id=NAME, .sl_int64=(VALUE)} #define PySlot_UINT64(NAME, VALUE) \ {.sl_id=NAME, .sl_uint64=(VALUE)} #define PySlot_STATIC_DATA(NAME, VALUE) \ {.sl_id=NAME, .sl_flags=PySlot_STATIC, .sl_ptr=(VALUE)}
Added in version 3.15.
-
PySlot_END¶
- This macro is available when compiling for the Stable ABI (バージョン 3.15 より).
PySlot配列の終端を示すための便利なマクロです。次のように定義されています。
#define PySlot_END {0}Added in version 3.15.
-
PySlot_PTR(name, value)¶
-
PySlot_PTR_STATIC(name, value)¶
- This macro is available when compiling for the Stable ABI (バージョン 3.15 より).
C++11 互換のコードで使うための便利なマクロです。 このバージョンの C++ では、リテラルで任意の共用体メンバーを設定できません。 代わりに、これらのマクロは
PySlot_INTPTRフラグを設定し、値を(void*)にキャストします。次のように定義されています。
#define PySlot_PTR(NAME, VALUE) \ {NAME, PySlot_INTPTR, {0}, {(void*)(VALUE)}} #define PySlot_PTR_STATIC(NAME, VALUE) \ {NAME, PySlot_INTPTR|Py_SLOT_STATIC, {0}, {(void*)(VALUE)}}
Added in version 3.15.
共通のスロット ID¶
次のスロット ID は、型の定義とモジュールの定義の両方で使えます。
-
Py_slot_end¶
- 次に属します: Stable ABI (バージョン 3.15 より).
スロット配列の終端を示します。 ゼロと定義されています。
Added in version 3.15.
-
Py_slot_subslots¶
- 次に属します: Stable ABI (バージョン 3.15 より).
ネストしたスロット配列。
値 (
sl_ptr) はPySlot構造体の配列を指す必要があります。 配列内のスロットは、ID がゼロの終端エントリーの直前まで、現在のスロット配列のPy_slot_subslotsの位置に挿入されたものとして扱われます。スロットのネストの深さは 5 段階に制限されています。 この制限は将来取り除かれる可能性があります。
Added in version 3.15.
-
Py_slot_invalid¶
- 次に属します: Stable ABI (バージョン 3.15 より).
予約済みです。 常に未知のスロット ID として扱われます。
UINT16_MAX(0xFFFF) と定義されています。PySlot_OPTIONALフラグとともに使うと、何の効果もないスロットを定義します。 このフラグがない場合、この ID のスロットの処理は失敗します。Added in version 3.15.