Definition slots
To define module objects <moduleobjects> and classes <creating-heap-types> using the C API, you may use an array of slots -- essentially, key-value pairs that describe features of the object to create. This decouples the data from the structures used at runtime, allowing CPython -- and other Python C API implementations -- to update the structures without breaking backwards compatibility.
This section documents slots in general. For object-specific behavior and slot values, see documentation for functions that apply slots:
PyType_FromSlotsfor types;PyModule_FromSlotsAndSpecandextension-export-hookfor modules.
When slots are passed to a function that applies them, the function will not modify the slot array, nor any data it points to (recursively). After the function is done, the caller is allowed to modify or deallocate the array and any data it points to (recursively), except data explicitly marked with PySlot_STATIC.
Except when documented otherwise, multiple slots with the same ID (~PySlot.sl_id) may not occur in a single slots array.
3.15
Slot arrays generalize an earlier way of defining objects: using PyType_Spec with PyType_Slot for types, and PyModuleDef with PyModuleDef_Slot for modules. The earlier API is soft deprecated; there are no plans to remove it.
Entries of the slots array use the following structure:
An entry in a slots array. Defined as:
typedef struct { uint16_t sl_id; uint16_t sl_flags; union { uint32_t sl_reserved; // must be 0 }; union { void *sl_ptr; void (*sl_func)(void); Py_ssize_t sl_size; int64_t sl_int64; uint64_t sl_uint64; }; } PySlot;A slot ID, chosen from:
Py_slot_*values documented inpyslot-common-idsbelow;Py_mod_*values for modules, as documented inc_module_slots;- Values for types, as documented in
pyslot_type_slot_ids.A
!sl_idof zero (Py_slot_end) marks the end of a slots array.Zero or more of the following flags, OR-ed together:
All data the slot points to is statically allocated and constant. Thus, the interpreter does not need to copy the information.
This flag is implied for function pointers.
The flag applies even to data the slot points to “indirectly”, except for slots nested via
Py_slot_subslotswhich may have their own!PySlot_STATICflags. For example, if applied to aPy_tp_membersslot that points to an array ofPyMemberDefstructures, then the entire array, as well as the name and doc strings in its elements, must be static and constant.The data is stored in
sl_ptr; CPython will cast it to the appropriate type.This flag can simplify porting from the older
PyType_SlotandPyModuleDef_Slotstructures.If the slot ID is unknown, the interpreter should ignore the slot, rather than fail.
For example, if Python 3.16 adds a new feature with a new slot ID,attr the corresponding slot may be marked
!PySlot_OPTIONALso that Python 3.15 ignores it.Note that the "optionality" only applies to unknown slot IDs. This flag does not make Python skip invalid values of known slots.
3.15
Convenience macros
Convenience macro to mark the end of a
!PySlotarray.Defined as:
#define PySlot_END {0}3.15
Common slot IDs
The following slot IDs may be used in both type and module definitions.
Marks the end of a slots array. Defined as zero.
3.15
Nested slots array.
The value (
~PySlot.sl_ptr) should point to an array ofPySlotstructures. The slots in the array (up to but not including the zero-ID terminator) will be treated as if they were inserted if the current slot array, at the point!Py_slot_subslotsappears.Slot nesting depth is limited to 5 levels. This restriction may be lifted in the future.
3.15
Reserved; will always be treated as an unknown slot ID. Defined as
UINT16_MAX(0xFFFF).When used with the
PySlot_OPTIONALflag, defines a slot with no effect. Without the flag, processing a slot with this ID will fail.3.15
谢谢你的反馈!