Содержание страницы
Слоты определения¶Definition slots
Чтобы определить объекты модулей и классы с помощью C API, можно использовать массив слотов – по сути, пары «ключ-значение», описывающие характеристики создаваемого объекта. Это разделяет данные и структуры, используемые во время выполнения, что позволяет CPython – и другим реализациям C API Python – обновлять структуры без нарушения обратной совместимости.
В этом разделе описаны слоты в общем. Сведения о поведении конкретных объектов и значениях слотов см. в документации функций, которые применяют слоты:
PyType_FromSlots()для типов;PyModule_FromSlotsAndSpec()и хук экспорта расширения для модулей.
Когда слоты передаются функции, которая их применяет, функция
не изменяет массив слотов и любые данные, на которые он указывает (рекурсивно).
После завершения функции вызывающий код может изменять или освобождать
массив и любые данные, на которые он указывает (рекурсивно), за исключением данных,
явно помеченных PySlot_STATIC.
Если не указано иное, в одном массиве слотов не должно быть нескольких слотов с одинаковым ID
(sl_id).
Добавлено в версии 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; uint32_t _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¶
Идентификатор слота, выбираемый из:
Py_slot_*значения, описанные в Общих идентификаторах слотов ниже;Py_mod_*значения для модулей, как описано в Определении модулей;Значения для типов, как описано в Идентификаторах слотов типов.
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¶
Данные для слота. Эти поля являются частью анонимного объединения; используемое поле зависит от типа данных, требуемого идентификатором слота: указатель на данные, указатель на функцию, размер, знаковое или беззнаковое целое число соответственно.
Если для конкретного идентификатора слота не указано иное, указатели (т.е.
sl_ptrиsl_func) не могут быть NULL.
-
uint16_t sl_flags¶
Ноль или более следующих флагов, объединённых операцией ИЛИ:
-
PySlot_STATIC¶
- Часть Stable ABI начиная с версии 3.15.
Все данные, на которые указывает слот, статически размещены и константны. Таким образом, интерпретатору не нужно копировать эту информацию.
Этот флаг подразумевается для указателей на функции.
Флаг применяется даже к данным, на которые слот указывает «косвенно», за исключением слотов, вложенных через
Py_slot_subslots, которые могут иметь собственные флагиPySlot_STATIC. Например, если применить его к слотуPy_tp_members, который указывает на массив структурPyMemberDef, то весь массив, а также строки имени и документации в его элементах должны быть статическими и константными.
-
PySlot_INTPTR¶
- Часть Stable ABI начиная с версии 3.15.
Данные хранятся в
sl_ptr; CPython приведёт их к соответствующему типу.Этот флаг может упростить перенос из старых структур
PyType_SlotиPyModuleDef_Slot.
-
PySlot_OPTIONAL¶
- Часть Stable ABI начиная с версии 3.15.
Если идентификатор слота неизвестен, интерпретатор должен игнорировать слот, а не завершаться с ошибкой.
Например, если Python 3.16 добавляет новую возможность с новым идентификатором слота,attr соответствующий слот может быть помечен
PySlot_OPTIONAL, чтобы Python 3.15 игнорировал его.Обратите внимание: «опциональность» применяется только к неизвестным идентификаторам слотов. Этот флаг не заставляет Python пропускать недопустимые значения известных слотов.
-
PySlot_STATIC¶
Добавлено в версии 3.15.
-
uint16_t sl_id¶
Вспомогательные макросы¶Convenience macros
-
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)¶
- Часть Stable ABI начиная с версии 3.15.
Вспомогательные макросы для определения структур
PySlotсsl_idи определённым набором элементов объединения.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)}
Добавлено в версии 3.15.
-
PySlot_END¶
- Часть Stable ABI начиная с версии 3.15.
Вспомогательный макрос для обозначения конца массива
PySlot.Определено как:
#define PySlot_END {0}Добавлено в версии 3.15.
-
PySlot_PTR(name, value)¶
-
PySlot_PTR_STATIC(name, value)¶
- Часть 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)}}
Добавлено в версии 3.15.
Общие идентификаторы слотов¶Common slot IDs
Следующие идентификаторы слотов можно использовать как в определениях типов, так и в определениях модулей.
-
Py_slot_end¶
- Часть Stable ABI начиная с версии 3.15.
Обозначает конец массива слотов. Определено как ноль.
Добавлено в версии 3.15.
-
Py_slot_subslots¶
- Часть Stable ABI начиная с версии 3.15.
Вложенный массив слотов.
Значение (
sl_ptr) должно указывать на массив структурPySlot. Слоты в массиве (до нулевого терминатора, не включая его) будут обрабатываться так, как если бы они были вставлены в текущий массив слотов в точке появленияPy_slot_subslots.Глубина вложенности слотов ограничена 5 уровнями. Это ограничение может быть снято в будущем.
Добавлено в версии 3.15.
-
Py_slot_invalid¶
- Часть Stable ABI начиная с версии 3.15.
Зарезервировано; всегда будет рассматриваться как неизвестный идентификатор слота. Определяется как
UINT16_MAX(0xFFFF).При использовании с флагом
PySlot_OPTIONALопределяет слот без эффекта. Без флага обработка слота с таким идентификатором завершится ошибкой.Добавлено в версии 3.15.