定義用スロット

C API で モジュールオブジェクト や クラス を定義するには、スロット の配列を使えます。 スロットは基本的にはキーと値の組で、作成するオブジェクトの機能を記述します。 これにより、定義用のデータと実行時の構造体を切り離し、CPython や他の Python C API 実装が後方互換性を壊さずに構造体を変更できるようになります。

この節ではスロット全般を説明します。 オブジェクト固有の動作やスロットの値については、スロットを適用する関数の説明を参照してください。

スロットを適用する関数に渡すとき、その関数はスロット配列も、配列が指すデータも (再帰的にたどった先を含めて) 変更しません。 関数が完了した後は、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。

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 にだけ適用される点に注意してください。 既知のスロットの無効な値が、このフラグによって無視されることはありません。

Added in version 3.15.

便利なマクロ

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.