> **Источник:** https://python-all.ru/3.16/c-api/type.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# Объекты типов

#### `type PyTypeObject`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) (как непрозрачная структура).*

C-структура объектов, используемая для описания встроенных типов.

#### `PyTypeObject PyType_Type`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable).*

Это объект типа для объектов-типов; он совпадает с объектом [`type`](https://python-all.ru/3.16/library/functions.html#type) на уровне Python.

#### `int PyType_Check(PyObject *o)`

Возвращает ненулевое значение, если объект *o* является объектом-типом, включая экземпляры типов, производных от стандартного объекта-типа. Возвращает 0 во всех остальных случаях. Эта функция всегда завершается успешно.

#### `int PyType_CheckExact(PyObject *o)`

Возвращает ненулевое значение, если объект *o* является объектом-типом, но не подтипом стандартного объекта-типа. Возвращает 0 во всех остальных случаях. Эта функция всегда завершается успешно.

#### `unsigned int PyType_ClearCache()`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable).*

Очищает внутренний кеш поиска. Возвращает текущий тег версии.

#### `unsigned long PyType_GetFlags(PyTypeObject *type)`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable).*

Возвращает член [`tp_flags`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_flags) объекта *type*. Эта функция в первую очередь предназначена для использования с `Py_LIMITED_API`; отдельные биты флагов гарантированно стабильны между версиями Python, но доступ к самому `tp_flags` не является частью [ограниченного API](https://python-all.ru/3.16/c-api/stable.html#limited-c-api).

Добавлено в версии 3.2.

Изменено в версии 3.4: Тип возвращаемого значения теперь `unsigned long`, а не `long`.

#### `PyObject *PyType_GetDict(PyTypeObject *type)`

Возвращает внутреннее пространство имён объекта-типа, которое иначе доступно только через прокси только для чтения ([`cls.__dict__`](https://python-all.ru/3.16/reference/datamodel.html#type.__dict__)). Это замена прямого доступа к [`tp_dict`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_dict). Возвращаемый словарь должен рассматриваться как доступный только для чтения.

Эта функция предназначена для конкретных случаев встраивания и привязки к языкам, где необходим прямой доступ к словарю, а косвенный доступ (например, через прокси или [`PyObject_GetAttr()`](https://python-all.ru/3.16/c-api/object.html#c.PyObject_GetAttr)) недостаточен.

Модули расширений должны продолжать использовать `tp_dict`, напрямую или косвенно, при создании собственных типов.

Добавлено в версии 3.12.

#### `void PyType_Modified(PyTypeObject *type)`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable).*

Аннулирует внутренний кеш поиска для типа и всех его подтипов. Эта функция должна вызываться после любого ручного изменения атрибутов или базовых классов типа.

#### `int PyType_AddWatcher(PyType_WatchCallback callback)`

Регистрирует *колбэк* в качестве наблюдателя за типами. Возвращает неотрицательный целочисленный идентификатор, который должен передаваться в последующие вызовы [`PyType_Watch()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Watch). В случае ошибки (например, закончились доступные идентификаторы наблюдателей) возвращает `-1` и устанавливает исключение.

В сборках со свободной многопоточностью [`PyType_AddWatcher()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_AddWatcher) не является потокобезопасным, поэтому он должен вызываться при запуске (до создания первого потока).

Добавлено в версии 3.12.

#### `int PyType_ClearWatcher(int watcher_id)`

Удаляет наблюдателя, идентифицированного по *watcher\_id* (ранее возвращённого из [`PyType_AddWatcher()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_AddWatcher)). Возвращает `0` при успехе, `-1` при ошибке (например, если *watcher\_id* никогда не был зарегистрирован).

Расширение никогда не должно вызывать `PyType_ClearWatcher` с *watcher\_id*, который не был возвращён ему предыдущим вызовом [`PyType_AddWatcher()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_AddWatcher).

Добавлено в версии 3.12.

#### `int PyType_Watch(int watcher_id, PyObject *type)`

Помечает *type* как наблюдаемый. Колбэк, получивший *watcher\_id* от [`PyType_AddWatcher()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_AddWatcher), будет вызываться каждый раз, когда [`PyType_Modified()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Modified) сообщает об изменении *type*. (Колбэк может вызываться только один раз для серии последовательных изменений *type*, если `_PyType_Lookup()` не вызывается для *type* между изменениями; это деталь реализации и может измениться.)

Колбэк также вызывается при освобождении наблюдаемого типа, размещённого в куче.

Расширение никогда не должно вызывать `PyType_Watch` с *watcher\_id*, который не был возвращён ему предыдущим вызовом [`PyType_AddWatcher()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_AddWatcher).

Добавлено в версии 3.12.

Изменено в версии 3.15: Теперь колбэк также вызывается при освобождении наблюдаемого типа, размещённого в куче.

#### `int PyType_Unwatch(int watcher_id, PyObject *type)`

Помечает *type* как неотслеживаемый. Это отменяет предыдущий вызов [`PyType_Watch()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Watch). *type* не должен быть `NULL`.

Расширение никогда не должно вызывать эту функцию с *watcher\_id*, который не был возвращён ему предыдущим вызовом [`PyType_AddWatcher()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_AddWatcher).

При успехе функция возвращает `0`. При неудаче функция возвращает `-1` с установленным исключением.

Добавлено в версии 3.12.

#### `typedef int (*PyType_WatchCallback)(PyObject *type)`

Тип колбэк-функции отслеживания типов.

Колбэк не должен изменять *type* или приводить к вызову [`PyType_Modified()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Modified) для *type* или любого типа в его MRO; нарушение этого правила может привести к бесконечной рекурсии.

Колбэк может вызываться во время освобождения типа. В этом случае объект типа временно воскрешается (его счётчик ссылок не меньше 1), и все его атрибуты остаются корректными. Однако колбэк не должен сохранять новые сильные ссылки на тип, так как это воскресит объект и предотвратит его освобождение.

Добавлено в версии 3.12.

Изменено в версии 3.15: Теперь колбэк может вызываться во время освобождения отслеживаемого динамического типа.

#### `int PyType_HasFeature(PyTypeObject *o, int feature)`

Возвращает ненулевое значение, если объект типа *o* устанавливает признак *feature*. Признаки типов обозначаются одноразрядными флагами.

#### `int PyType_FastSubclass(PyTypeObject *type, int flag)`

Возвращает ненулевое значение, если объект типа *type* устанавливает флаг подкласса *flag*. Флаги подклассов обозначаются [`Py_TPFLAGS_*_SUBCLASS`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_TPFLAGS_LONG_SUBCLASS). Эта функция используется многими функциями `_Check` для распространённых типов.

> **См. также**
>
> [`PyObject_TypeCheck()`](https://python-all.ru/3.16/c-api/object.html#c.PyObject_TypeCheck), который используется как более медленная альтернатива в функциях `_Check` для типов, не имеющих флагов подклассов.

#### `int PyType_IS_GC(PyTypeObject *o)`

Возвращает истину, если объект типа поддерживает детектор циклов; это проверяет флаг типа [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_TPFLAGS_HAVE_GC).

#### `int PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable).*

Возвращает истину, если *a* является подтипом *b*.

Эта функция проверяет только непосредственные подтипы, то есть [`__subclasscheck__()`](https://python-all.ru/3.16/reference/datamodel.html#type.__subclasscheck__) не вызывается для *b*. Вызовите [`PyObject_IsSubclass()`](https://python-all.ru/3.16/c-api/object.html#c.PyObject_IsSubclass), чтобы выполнить ту же проверку, что и [`issubclass()`](https://python-all.ru/3.16/library/functions.html#issubclass) .

#### `PyObject *PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)`

*Возвращаемое значение: новая ссылка.*

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable).*

Общий обработчик для слота [`tp_alloc`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_alloc) объекта типа. Использует механизм выделения памяти Python по умолчанию для выделения памяти под новый экземпляр, обнуляет память, а затем инициализирует её, как при вызове [`PyObject_Init()`](https://python-all.ru/3.16/c-api/allocation.html#c.PyObject_Init) или [`PyObject_InitVar()`](https://python-all.ru/3.16/c-api/allocation.html#c.PyObject_InitVar).

Не вызывайте это напрямую для выделения памяти под объект; вместо этого вызывайте слот [`tp_alloc`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_alloc) типа.

Для типов, поддерживающих сборку мусора (т.е. установлен флаг [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_TPFLAGS_HAVE_GC)), эта функция ведёт себя как [`PyObject_GC_New`](https://python-all.ru/3.16/c-api/gcsupport.html#c.PyObject_GC_New) или [`PyObject_GC_NewVar`](https://python-all.ru/3.16/c-api/gcsupport.html#c.PyObject_GC_NewVar) (за исключением того, что память гарантированно обнуляется перед инициализацией), и должна использоваться в паре с [`PyObject_GC_Del()`](https://python-all.ru/3.16/c-api/gcsupport.html#c.PyObject_GC_Del) в [`tp_free`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_free). В противном случае она ведёт себя как [`PyObject_New`](https://python-all.ru/3.16/c-api/allocation.html#c.PyObject_New) или [`PyObject_NewVar`](https://python-all.ru/3.16/c-api/allocation.html#c.PyObject_NewVar) (с той же гарантией обнуления) и должна использоваться в паре с [`PyObject_Free()`](https://python-all.ru/3.16/c-api/memory.html#c.PyObject_Free) в `tp_free`.

#### `PyObject *PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)`

*Возвращаемое значение: новая ссылка.*

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable).*

Общий обработчик для слота [`tp_new`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_new) объекта типа. Создаёт новый экземпляр, используя слот [`tp_alloc`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_alloc) типа, и возвращает полученный объект.

#### `int PyType_Ready(PyTypeObject *type)`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable).*

Завершает инициализацию объекта типа. Должна вызываться для всех объектов типа, чтобы завершить их инициализацию. Эта функция отвечает за добавление наследуемых слотов из базового класса. Возвращает `0` при успехе, или `-1` и устанавливает исключение при ошибке.

> **Примечание**
>
> If some of the base classes implements the GC protocol and the provided type does not include the [`Py_TPFLAGS_HAVE_GC`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_TPFLAGS_HAVE_GC) in its flags, then the GC protocol will be automatically implemented from its parents. On the contrary, if the type being created does include `Py_TPFLAGS_HAVE_GC` in its flags then it **must** implement the GC protocol itself by at least implementing the [`tp_traverse`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_traverse) handle.

#### `PyObject *PyType_GetName(PyTypeObject *type)`

*Возвращаемое значение: новая ссылка.*

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.11.*

Возвращает имя типа. Эквивалентно получению атрибута [`__name__`](https://python-all.ru/3.16/reference/datamodel.html#type.__name__) типа.

Добавлено в версии 3.12.

#### `PyObject *PyType_GetQualName(PyTypeObject *type)`

*Возвращаемое значение: новая ссылка.*

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.11.*

Возвращает квалифицированное имя типа. Эквивалентно получению атрибута [`__qualname__`](https://python-all.ru/3.16/reference/datamodel.html#type.__qualname__) типа.

Добавлено в версии 3.12.

#### `PyObject *PyType_GetFullyQualifiedName(PyTypeObject *type)`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable), начиная с версии 3.13.*

Возвращает полное квалифицированное имя типа. Эквивалентно `f"{type.__module__}.{type.__qualname__}"` или [`type.__qualname__`](https://python-all.ru/3.16/reference/datamodel.html#type.__qualname__), если [`type.__module__`](https://python-all.ru/3.16/reference/datamodel.html#type.__module__) не является строкой или равно `"builtins"`.

Добавлено в версии 3.13.

#### `PyObject *PyType_GetModuleName(PyTypeObject *type)`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable), начиная с версии 3.13.*

Возвращает имя модуля типа. Эквивалентно получению атрибута [`type.__module__`](https://python-all.ru/3.16/reference/datamodel.html#type.__module__).

Добавлено в версии 3.13.

#### `void *PyType_GetSlot(PyTypeObject *type, int slot)`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.4.*

Возвращает указатель на функцию, хранящийся в указанном слоте. Если результат равен `NULL`, это означает, что либо слот `NULL`, либо функция была вызвана с недопустимыми параметрами. Обычно вызывающий код приводит указатель результата к соответствующему типу функции.

См. [`PyType_Slot.slot`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Slot.slot) для возможных значений аргумента *slot*.

Добавлено в версии 3.4.

Изменено в версии 3.10: [`PyType_GetSlot()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_GetSlot) теперь может принимать все типы. Ранее он был ограничен [динамическими типами (heap types)](https://python-all.ru/3.16/c-api/typeobj.html#heap-types).

#### `PyObject *PyType_GetModule(PyTypeObject *type)`

*Возвращаемое значение: заимствованная ссылка.*

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.10.*

Возвращает объект модуля, связанный с данным типом, если тип был создан с помощью [`PyType_FromModuleAndSpec()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_FromModuleAndSpec).

Возвращаемая ссылка является [заимствованной](https://python-all.ru/3.16/glossary.html#term-borrowed-reference) от *type* и будет действительна, пока существует ссылка на *type*. Не освобождайте её с помощью [`Py_DECREF()`](https://python-all.ru/3.16/c-api/refcounting.html#c.Py_DECREF) или аналогичных средств.

Если с данным типом не связан ни один модуль, устанавливает [`TypeError`](https://python-all.ru/3.16/library/exceptions.html#TypeError) и возвращает `NULL`.

Эта функция обычно используется для получения модуля, в котором определён метод. Обратите внимание, что в таком методе `PyType_GetModule(Py_TYPE(self))` может вернуть неожиданный результат. `Py_TYPE(self)` может быть *подклассом* целевого класса, а подклассы не обязательно определены в том же модуле, что и их суперкласс. См. [`PyCMethod`](https://python-all.ru/3.16/c-api/structures.html#c.PyCMethod) для получения класса, определяющего метод. См. [`PyType_GetModuleByToken()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_GetModuleByToken) для случаев, когда `PyCMethod` нельзя использовать.

Добавлено в версии 3.9.

#### `void *PyType_GetModuleState(PyTypeObject *type)`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.10.*

Возвращает состояние объекта модуля, связанного с данным типом. Это сокращение для вызова [`PyModule_GetState()`](https://python-all.ru/3.16/c-api/module.html#c.PyModule_GetState) для результата [`PyType_GetModule()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_GetModule).

Если с данным типом не связан ни один модуль, устанавливает [`TypeError`](https://python-all.ru/3.16/library/exceptions.html#TypeError) и возвращает `NULL`.

Если с *type* связан модуль, но его состояние равно `NULL`, возвращает `NULL` без установки исключения.

Добавлено в версии 3.9.

#### `PyObject *PyType_GetModuleByToken(PyTypeObject *type, const void *mod_token)`

*Возвращаемое значение: новая ссылка.*

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.15.*

Находит первый суперкласс, модуль которого имеет указанный [токен модуля](https://python-all.ru/3.16/c-api/module.html#ext-module-token), и возвращает этот модуль.

Если модуль не найден, возбуждает [`TypeError`](https://python-all.ru/3.16/library/exceptions.html#TypeError) и возвращает `NULL`.

Эта функция предназначена для использования совместно с [`PyModule_GetState()`](https://python-all.ru/3.16/c-api/module.html#c.PyModule_GetState) для получения состояния модуля из слотовых методов (таких как [`tp_init`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_init) или [`nb_add`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyNumberMethods.nb_add)) и других мест, где определяющий класс метода не может быть передан с помощью соглашения о вызове [`PyCMethod`](https://python-all.ru/3.16/c-api/structures.html#c.PyCMethod).

Добавлено в версии 3.15.

#### `PyObject *PyType_GetModuleByDef(PyTypeObject *type, struct PyModuleDef *def)`

*Возвращаемое значение: заимствованная ссылка.*

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.13.*

Находит первый суперкласс, модуль которого был создан из указанного [`PyModuleDef`](https://python-all.ru/3.16/c-api/module.html#c.PyModuleDef) *def*, или чей [токен модуля](https://python-all.ru/3.16/c-api/module.html#ext-module-token) равен *def*, и возвращает этот модуль.

Обратите внимание, что модули, созданные из [`PyModuleDef`](https://python-all.ru/3.16/c-api/module.html#c.PyModuleDef), всегда имеют свой токен, установленный на адрес `PyModuleDef`. Другими словами, эта функция эквивалентна [`PyType_GetModuleByToken()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_GetModuleByToken), за исключением того, что она:

- возвращает заимствованную ссылку, и
- имеет тип аргумента, отличный от `void*` (что является косметическим различием в C).

Возвращаемая ссылка является [заимствованной](https://python-all.ru/3.16/glossary.html#term-borrowed-reference) от *type* и будет действительна, пока существует ссылка на *type*. Не освобождайте её с помощью [`Py_DECREF()`](https://python-all.ru/3.16/c-api/refcounting.html#c.Py_DECREF) или аналогичных средств.

Добавлено в версии 3.12.

#### `int PyType_GetBaseByToken(PyTypeObject *type, void *tp_token, PyTypeObject **result)`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.14.*

Находит первый суперкласс в *type* в [порядке разрешения методов](https://python-all.ru/3.16/glossary.html#term-method-resolution-order), чей [`Py_tp_token`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_token) токен равен *tp\_token*.

- Если найдено, установить *\*result* в новую [сильную ссылку](https://python-all.ru/3.16/glossary.html#term-strong-reference) на него и вернуть `1`.
- Если не найдено, установить *\*result* в `NULL` и вернуть `0`.
- При ошибке установить *\*result* в `NULL` и вернуть `-1` с установленным исключением.

Аргумент *result* может быть равен `NULL`, и в этом случае *\*result* не устанавливается. Используйте это, если нужно только возвращаемое значение.

Аргумент *tp\_token* не может быть равен `NULL`.

Добавлено в версии 3.14.

#### `int PyUnstable_Type_AssignVersionTag(PyTypeObject *type)`

> *Это [нестабильное API](https://python-all.ru/3.16/c-api/stable.html#unstable-c-api). Оно может меняться без предупреждения в минорных версиях.*

Пытается назначить версионный тег заданному типу.

Возвращает 1, если тип уже имел допустимый версионный тег или был назначен новый, или 0, если новый тег не удалось назначить.

Добавлено в версии 3.12.

#### `int PyType_SUPPORTS_WEAKREFS(PyTypeObject *type)`

Возвращает true, если экземпляры *type* поддерживают создание слабых ссылок, и false в противном случае. Эта функция всегда завершается успешно. *type* не должен быть `NULL`.

> **См. также**
>
> - [Объекты слабых ссылок](https://python-all.ru/3.16/c-api/weakref.html#weakrefobjects)
> - [`weakref`](https://python-all.ru/3.16/library/weakref.html#module-weakref)

## Создание типов, размещаемых в куче

Следующая функция используется для создания [типов, размещаемых в куче](https://python-all.ru/3.16/c-api/typeobj.html#heap-types):

#### `PyObject *PyType_FromSlots(const PySlot *slots)`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.15.*

Создаёт и возвращает [тип, размещаемый в куче](https://python-all.ru/3.16/c-api/typeobj.html#heap-types), из массива `PySlot` . Смотрите [Определение слотов](https://python-all.ru/3.16/c-api/slots.html#capi-slots) для общей информации о слотах, и [Идентификаторы слотов типов](https://python-all.ru/3.16/c-api/type.html#pyslot-type-slot-ids) для слотов, специфичных для создания типов.

Эта функция вызывает [`PyType_Ready()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Ready) для нового типа.

Обратите внимание, что эта функция *не* полностью соответствует поведению вызова [`type()`](https://python-all.ru/3.16/library/functions.html#type) или использования оператора [`class`](https://python-all.ru/3.16/reference/compound_stmts.html#class). С пользовательскими базовыми типами или метаклассами предпочтительнее [вызов](https://python-all.ru/3.16/c-api/call.html#capi-call) `type` (или метакласса) вместо функций `PyType_From*`. В частности:

- [`__new__()`](https://python-all.ru/3.16/reference/datamodel.html#object.__new__) не вызывается для нового класса (и должен быть установлен в `type.__new__`).
- [`__init__()`](https://python-all.ru/3.16/reference/datamodel.html#object.__init__) не вызывается для нового класса.
- [`__init_subclass__()`](https://python-all.ru/3.16/reference/datamodel.html#object.__init_subclass__) не вызывается ни для каких базовых классов.
- [`__set_name__()`](https://python-all.ru/3.16/reference/datamodel.html#object.__set_name__) не вызывается для новых дескрипторов.

Слоты обычно определяются как глобальные статические константные массивы. Однако иногда значения слотов не известны статически на этапе компиляции. Например, такие слоты, как [`Py_tp_bases`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_bases), [`Py_tp_metaclass`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_metaclass) и [`Py_tp_module`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_module), требуют живых объектов Python. В этом случае рекомендуется размещать такие слоты на стеке и использовать [`Py_slot_subslots`](https://python-all.ru/3.16/c-api/slots.html#c.Py_slot_subslots) для ссылки на массив статических слотов. Например:

```c
static const PySlot my_slots[] = {
   PySlot_STATIC_DATA(Py_tp_name, "MyClass"),
   PySlot_FUNC(Py_tp_repr, my_repr_func),
   ...
   PySlot_END
};

PyObject *make_my_class(PyObject *module) {
   PySlot all_slots[] = {
      PySlot_STATIC_DATA(Py_slot_subslots, my_slots),
      PySlot_DATA(Py_tp_module, module),
      PySlot_END
   };
   return PyType_FromSlots(all_slots);
}
```

Типы, размещаемые в куче, созданные без флага [`Py_TPFLAGS_IMMUTABLETYPE`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_TPFLAGS_IMMUTABLETYPE), могут быть изменены, например, путём установки атрибутов, как и классы, определённые в коде Python. Иногда такие изменения необходимы для полной инициализации типа, но может потребоваться запретить пользователям изменять тип после завершения инициализации:

#### `int PyType_Freeze(PyTypeObject *type)`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.14.*

Делает тип неизменяемым: установить флаг [`Py_TPFLAGS_IMMUTABLETYPE`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_TPFLAGS_IMMUTABLETYPE).

Все базовые классы *type* должны быть неизменяемыми.

При успехе возвращает `0`. При ошибке устанавливает исключение и возвращает `-1`.

Тип не должен использоваться до того, как он станет неизменяемым. Например, экземпляры типа не должны создаваться до того, как тип станет неизменяемым.

Добавлено в версии 3.14.

### Идентификаторы слотов типов

Большинство идентификаторов слотов типов именуются по образцу названий полей структур [`PyTypeObject`](https://python-all.ru/3.16/c-api/type.html#c.PyTypeObject), [`PyNumberMethods`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyNumberMethods), [`PySequenceMethods`](https://python-all.ru/3.16/c-api/typeobj.html#c.PySequenceMethods), [`PyMappingMethods`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyMappingMethods) и [`PyAsyncMethods`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyAsyncMethods) с добавлением префикса `Py_`. Например, используйте:

- [`Py_tp_dealloc`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_tp_dealloc) для установки [`PyTypeObject.tp_dealloc`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_dealloc)
- [`Py_nb_add`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_nb_add) для установки [`PyNumberMethods.nb_add`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyNumberMethods.nb_add)
- [`Py_sq_length`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_sq_length) для установки [`PySequenceMethods.sq_length`](https://python-all.ru/3.16/c-api/typeobj.html#c.PySequenceMethods.sq_length)

Следующие слоты требуют дополнительного рассмотрения при указании в качестве слотов:

- [`Py_tp_name`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_name)
- [`Py_tp_basicsize`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_basicsize) и [`Py_tp_extra_basicsize`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_extra_basicsize)
- [`Py_tp_itemsize`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_itemsize)
- [`Py_tp_flags`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_flags)

Дополнительные слоты не соответствуют напрямую полю структуры `PyTypeObject`:

- [`Py_tp_token`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_token)
- [`Py_tp_metaclass`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_metaclass)
- [`Py_tp_module`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_module)

Следующие поля «offset» нельзя задать с помощью [`PyType_Slot`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Slot):

- [`tp_weaklistoffset`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_weaklistoffset) (по возможности используйте [`Py_TPFLAGS_MANAGED_WEAKREF`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_TPFLAGS_MANAGED_WEAKREF) вместо этого)
- [`tp_dictoffset`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_dictoffset) (по возможности используйте [`Py_TPFLAGS_MANAGED_DICT`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_TPFLAGS_MANAGED_DICT) вместо этого)
- [`tp_vectorcall_offset`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_vectorcall_offset) (используйте `"__vectorcalloffset__"` в [PyMemberDef](https://python-all.ru/3.16/c-api/structures.html#pymemberdef-offsets))

Если невозможно переключиться на флаг `MANAGED` (например, для vectorcall или для поддержки Python версии ниже 3.12), укажите смещение в [`Py_tp_members`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_tp_members). Подробнее см. [документацию PyMemberDef](https://python-all.ru/3.16/c-api/structures.html#pymemberdef-offsets).

Следующие внутренние поля вообще нельзя задать при создании типа на куче:

- [`tp_dict`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_dict), [`tp_mro`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_mro), [`tp_cache`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_cache), [`tp_subclasses`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_subclasses) и [`tp_weaklist`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_weaklist).

Слот [`Py_tp_base`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_base) эквивалентен [`Py_tp_bases`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_bases); оба могут быть заданы как тип или кортеж типов. Если указаны оба, используется значение `Py_tp_bases`.

Значения слотов не могут быть `NULL`, за исключением следующих:

- [`Py_tp_doc`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_tp_doc)
- [`Py_tp_token`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_token) (для ясности предпочтительнее [`Py_TP_USE_SPEC`](https://python-all.ru/3.16/c-api/type.html#c.Py_TP_USE_SPEC), а не `NULL`)

Изменено в версии 3.9: Слоты в [`PyBufferProcs`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyBufferProcs) могут быть заданы в неограниченном API.

Изменено в версии 3.11: [`bf_getbuffer`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyBufferProcs.bf_getbuffer) и [`bf_releasebuffer`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyBufferProcs.bf_releasebuffer) теперь доступны в рамках [ограниченного API](https://python-all.ru/3.16/c-api/stable.html#limited-c-api).

Изменено в версии 3.14: Поле [`tp_vectorcall`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_vectorcall) теперь можно задать с помощью [`Py_tp_vectorcall`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_tp_vectorcall). Подробнее см. документацию поля.

Изменено в версии 3.15: Слот [`Py_tp_bases`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_bases) теперь может быть задан как одиночный объект типа, что делает его эквивалентным слоту [`Py_tp_base`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_base). Ранее требовался кортеж типов.

Следующие слоты соответствуют полям в базовой структуре типа, но требуют дополнительных замечаний при использовании в качестве слотов:

#### `Py_tp_name`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.15.*

[`Slot ID`](https://python-all.ru/3.16/c-api/slots.html#c.PySlot.sl_id) для имени типа, используется для установки [`PyTypeObject.tp_name`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_name).

Этот слот (или [`PyType_Spec.name`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec.name)) необходим для создания типа.

Это нельзя использовать в [`PyType_Spec.slots`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec.slots). Вместо этого используйте [`PyType_Spec.name`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec.name).

**Деталь реализации CPython:** CPython обрабатывает слоты по порядку. Рекомендуется помещать `Py_tp_name` в начало массива слотов, чтобы в случае сбоя обработки последующих слотов сообщения об ошибках содержали имя.

Добавлено в версии 3.15.

#### `Py_tp_basicsize`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.15.*

[`Slot ID`](https://python-all.ru/3.16/c-api/slots.html#c.PySlot.sl_id) для размера экземпляра в байтах. Используется для установки [`PyTypeObject.tp_basicsize`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_basicsize).

Значение должно быть положительным.

Это нельзя использовать в [`PyType_Spec.slots`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec.slots). Вместо этого используйте [`PyType_Spec.basicsize`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec.basicsize).

Этот слот нельзя использовать с [`PyType_GetSlot()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_GetSlot). При необходимости используйте [`PyTypeObject.tp_basicsize`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_basicsize), но учтите, что размер типа часто считается деталью реализации.

Добавлено в версии 3.15.

#### `Py_tp_extra_basicsize`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.15.*

[`Slot ID`](https://python-all.ru/3.16/c-api/slots.html#c.PySlot.sl_id) для размера данных типа в байтах, то есть сколько пространства *в дополнение* требуется экземплярам класса сверх пространства, необходимого для суперклассов.

Это значение используется вместе с размером суперклассов для установки [`PyTypeObject.tp_basicsize`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_basicsize). Python будет вставлять выравнивание по мере необходимости для соблюдения требований выравнивания `tp_basicsize`.

Используйте [`PyObject_GetTypeData()`](https://python-all.ru/3.16/c-api/object.html#c.PyObject_GetTypeData), чтобы получить указатель на память, зарезервированную таким образом для подкласса.

Значение должно быть положительным. Чтобы указать, что экземплярам не требуется дополнительный размер (то есть размер должен наследоваться), опустите слот `Py_tp_extra_basicsize`, а не устанавливайте его в ноль.

Указание одновременно [`Py_tp_basicsize`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_basicsize) и `Py_tp_extra_basicsize` является ошибкой.

Это нельзя использовать в [`PyType_Spec.slots`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec.slots). Вместо этого используйте отрицательное [`PyType_Spec.basicsize`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec.basicsize).

Этот слот нельзя использовать с [`PyType_GetSlot()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_GetSlot).

Добавлено в версии 3.15.

#### `Py_tp_itemsize`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.15.*

[`Slot ID`](https://python-all.ru/3.16/c-api/slots.html#c.PySlot.sl_id) для размера одного элемента типа с изменяемым размером, в байтах. Используется для установки [`PyTypeObject.tp_itemsize`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_itemsize). См. документацию `tp_itemsize` о возможных ограничениях.

Значение должно быть положительным.

Если этот слот отсутствует, [`tp_itemsize`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) наследуется. Расширение произвольных классов с изменяемым размером опасно, поскольку некоторые типы используют фиксированное смещение для памяти переменного размера, которая затем может перекрываться с памятью фиксированного размера, используемой подклассом. Чтобы помочь избежать ошибок, наследование `itemsize` возможно только в следующих ситуациях:

- Базовый класс не имеет изменяемого размера (его [`tp_itemsize`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_itemsize) равно нулю).
- Запрошенный [`PyType_Spec.basicsize`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec.basicsize) положителен, что говорит о том, что расположение памяти базового класса известно.
- Запрошенный [`PyType_Spec.basicsize`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec.basicsize) равен нулю, что говорит о том, что подкласс не обращается к памяти экземпляра напрямую.
- С флагом [`Py_TPFLAGS_ITEMS_AT_END`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_TPFLAGS_ITEMS_AT_END).

Это нельзя использовать в [`PyType_Spec.slots`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec.slots). Вместо этого используйте [`PyType_Spec.itemsize`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec.itemsize).

Этот слот нельзя использовать с [`PyType_GetSlot()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_GetSlot).

Добавлено в версии 3.15.

#### `Py_tp_flags`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.15.*

[`Slot ID`](https://python-all.ru/3.16/c-api/slots.html#c.PySlot.sl_id) для флагов типа, используется для установки [`PyTypeObject.tp_flags`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_flags).

Флаг `Py_TPFLAGS_HEAPTYPE` не установлен, [`PyType_FromSpecWithBases()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_FromSpecWithBases) устанавливает его автоматически.

Это нельзя использовать в [`PyType_Spec.slots`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec.slots). Вместо этого используйте отрицательное [`PyType_Spec.basicsize`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec.basicsize).

Этот слот нельзя использовать с [`PyType_GetSlot()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_GetSlot). Вместо этого используйте [`PyType_GetFlags()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_GetFlags).

Добавлено в версии 3.15.

#### `Py_tp_bases`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable).*

[`Slot ID`](https://python-all.ru/3.16/c-api/slots.html#c.PySlot.sl_id) для флагов типа, используется для установки [`PyTypeObject.tp_bases`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_bases).

Этот слот можно установить в кортеж объектов типа, от которых должен наследоваться вновь созданный тип, как «позиционные аргументы» [определения класса](https://python-all.ru/3.16/reference/compound_stmts.html#class) Python.

В качестве альтернативы слот можно установить в один объект типа, чтобы указать единственный базовый класс. Эффект аналогичен указанию кортежа из одного элемента.

Изменено в версии 3.15: Ранее `Py_tp_bases` требовал кортеж типов.

#### `Py_tp_base`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable).*

Эквивалентен [`Py_tp_bases`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_bases) (с `s` в конце). Если указаны оба, `Py_tp_bases` имеет приоритет, и этот слот игнорируется.

Изменено в версии 3.15: Ранее `Py_tp_base` требовал один тип, а не кортеж.

[Мягкое устаревание](https://python-all.ru/3.16/glossary.html#term-soft-deprecated) с версии 3.15: Если не требуется поддержка старых версий Python, предпочтительнее использовать `Py_tp_bases`.

Следующие слоты не соответствуют публичным полям в нижележащих структурах:

#### `Py_tp_metaclass`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.15.*

[`Slot ID`](https://python-all.ru/3.16/c-api/slots.html#c.PySlot.sl_id) для метакласса, используемого для создания результирующего объекта типа. Если опущен, метакласс выводится из базовых классов ([`Py_tp_bases`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_bases) или аргумента *bases* функции [`PyType_FromMetaclass()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_FromMetaclass)).

Метаклассы, которые переопределяют [`tp_new`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_new), не поддерживаются, за исключением случаев, когда `tp_new` равно `NULL`.

Это нельзя использовать в [`PyType_Spec.slots`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec.slots). Используйте [`PyType_FromMetaclass()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_FromMetaclass), чтобы указать метакласс с `PyType_Spec`.

Этот слот нельзя использовать с [`PyType_GetSlot()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_GetSlot). Вместо этого используйте [`Py_TYPE()`](https://python-all.ru/3.16/c-api/structures.html#c.Py_TYPE) на объекте типа.

Добавлено в версии 3.15.

#### `Py_tp_module`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.15.*

[`Slot ID`](https://python-all.ru/3.16/c-api/slots.html#c.PySlot.sl_id) для записи модуля, в котором определяется новый класс.

Значение должно быть объектом модуля. Модуль связывается с новым типом и может быть впоследствии получен с помощью [`PyType_GetModule()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_GetModule). Связанный модуль не наследуется подклассами; его необходимо указывать для каждого класса отдельно.

Это нельзя использовать в [`PyType_Spec.slots`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec.slots). Используйте [`PyType_FromMetaclass()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_FromMetaclass), чтобы указать модуль с `PyType_Spec`.

Этот слот нельзя использовать с [`PyType_GetSlot()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_GetSlot). Вместо этого используйте [`PyType_GetModule()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_GetModule).

Добавлено в версии 3.15.

#### `Py_tp_token`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.14.*

[`Slot ID`](https://python-all.ru/3.16/c-api/slots.html#c.PySlot.sl_id) для записи идентификатора статического расположения памяти для класса.

Если класс определён с помощью [`PyType_Spec`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec), и этот spec выделен статически, токен может быть установлен на этот spec с помощью специального значения [`Py_TP_USE_SPEC`](https://python-all.ru/3.16/c-api/type.html#c.Py_TP_USE_SPEC):

```c
static PyType_Slot foo_slots[] = {
   {Py_tp_token, Py_TP_USE_SPEC},
```

Его также можно установить на произвольный указатель, но необходимо убедиться, что:

- Указатель переживает класс, чтобы он не был повторно использован для чего-то другого пока класс существует.
- Он «принадлежит» тому модулю расширения, где находится класс, чтобы не конфликтовать с другими расширениями.

Используйте [`PyType_GetBaseByToken()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_GetBaseByToken), чтобы проверить, есть ли у суперкласса класса заданный токен – то есть, совместимо ли расположение памяти.

Чтобы получить токен для заданного класса (без учёта суперклассов), используйте [`PyType_GetSlot()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_GetSlot) с `Py_tp_token`.

Добавлено в версии 3.14.

#### `Py_TP_USE_SPEC`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.14.*

Используется как значение с [`Py_tp_token`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_token), чтобы установить токен на [`PyType_Spec`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Spec) класса. Может использоваться только для классов, определённых с помощью `PyType_Spec`.

Расширяется до `NULL`.

Добавлено в версии 3.14.

#### `Py_tp_slots`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.15.*

[`Slot ID`](https://python-all.ru/3.16/c-api/slots.html#c.PySlot.sl_id), который работает как [`Py_slot_subslots`](https://python-all.ru/3.16/c-api/slots.html#c.Py_slot_subslots), за исключением того, что он задаёт массив структур [`PyType_Slot`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Slot).

Добавлено в версии 3.15.

## Мягко устаревшее API

Следующие функции [мягко устарели](https://python-all.ru/3.16/glossary.html#term-soft-deprecated). Они продолжат работать, но новые возможности будут добавляться в виде слотов для [`PyType_FromSlots()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_FromSlots), а не в качестве аргументов новых функций `PyType_From*`.

#### `PyObject *PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases)`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.12.*

Создаёт и возвращает [кучевый тип](https://python-all.ru/3.16/c-api/typeobj.html#heap-types) из *spec* (см. [`Py_TPFLAGS_HEAPTYPE`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_TPFLAGS_HEAPTYPE)).

Аргумент *метакласс*, отличный от `NULL`, соответствует слоту [`Py_tp_metaclass`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_metaclass).

Аргумент *bases*, отличный от `NULL`, соответствует слоту [`Py_tp_bases`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_bases) и имеет приоритет над слотами `Py_tp_bases` и `Py_tp_bases`.

Аргумент *модуль*, отличный от `NULL`, соответствует слоту [`Py_tp_module`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_module).

Эта функция вызывает [`PyType_Ready()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Ready) у нового типа.

Обратите внимание, что эта функция *не* полностью повторяет поведение вызова [`type()`](https://python-all.ru/3.16/library/functions.html#type) или использования оператора [`class`](https://python-all.ru/3.16/reference/compound_stmts.html#class). Подробнее см. примечание в документации [`PyType_FromSlots()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_FromSlots).

Добавлено в версии 3.12.

[Мягкое устаревание](https://python-all.ru/3.16/glossary.html#term-soft-deprecated) с версии 3.16.0a0 (не выпущена): В новом коде используйте [`PyType_FromSlots()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_FromSlots).

#### `PyObject *PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)`

*Возвращаемое значение: новая ссылка.*

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.10.*

Эквивалентно `PyType_FromMetaclass(NULL, module, spec, bases)`.

Добавлено в версии 3.9.

Изменено в версии 3.10: Функция теперь принимает один класс в качестве аргумента *bases* и `NULL` в качестве слота `tp_doc`.

Изменено в версии 3.12: Функция теперь находит и использует метакласс, соответствующий переданным базовым классам. Ранее возвращались только экземпляры [`type`](https://python-all.ru/3.16/library/functions.html#type).

[`tp_new`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_new) метакласса *игнорируется*. что может привести к неполной инициализации. Создание классов, метакласс которых переопределяет `tp_new`, устарело.

Изменено в версии 3.14: Создание классов, метакласс которых переопределяет [`tp_new`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_new), больше не допускается.

[Мягкое устаревание](https://python-all.ru/3.16/glossary.html#term-soft-deprecated) с версии 3.16.0a0 (не выпущена): В новом коде используйте [`PyType_FromSlots()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_FromSlots).

#### `PyObject *PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)`

*Возвращаемое значение: новая ссылка.*

*Часть [стабильного ABI](https://python-all.ru/3.16/c-api/stable.html#stable) начиная с версии 3.3.*

Эквивалентно `PyType_FromMetaclass(NULL, NULL, spec, bases)`.

Добавлено в версии 3.3.

Изменено в версии 3.12: Теперь функция находит и использует метакласс, соответствующий указанным базовым классам. Ранее возвращались только экземпляры [`type`](https://python-all.ru/3.16/library/functions.html#type).

[`tp_new`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_new) метакласса *игнорируется*, что может привести к неполной инициализации. Создание классов, чей метакласс переопределяет `tp_new`, устарело.

Изменено в версии 3.14: Создание классов, чей метакласс переопределяет [`tp_new`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_new), больше не разрешено.

[Мягкое устаревание](https://python-all.ru/3.16/glossary.html#term-soft-deprecated) с версии 3.16.0a0 (не выпущена): В новом коде используйте [`PyType_FromSlots()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_FromSlots).

#### `PyObject *PyType_FromSpec(PyType_Spec *spec)`

*Возвращаемое значение: новая ссылка.*

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable).*

Эквивалентно `PyType_FromMetaclass(NULL, NULL, spec, NULL)`.

Изменено в версии 3.12: Теперь функция находит и использует метакласс, соответствующий базовым классам, указанным в слотах *Py\_tp\_base\[s\]*. Ранее возвращались только экземпляры [`type`](https://python-all.ru/3.16/library/functions.html#type).

[`tp_new`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_new) метакласса *игнорируется*, что может привести к неполной инициализации. Создание классов, чей метакласс переопределяет `tp_new`, устарело.

Изменено в версии 3.14: Создание классов, чей метакласс переопределяет [`tp_new`](https://python-all.ru/3.16/c-api/typeobj.html#c.PyTypeObject.tp_new), больше не разрешено.

[Мягкое устаревание](https://python-all.ru/3.16/glossary.html#term-soft-deprecated) с версии 3.16.0a0 (не выпущена): В новом коде используйте [`PyType_FromSlots()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_FromSlots).

Keep old URL fragments working (see gh-97908)

#### `type PyType_Spec`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) (включая все члены).*

Структура, определяющая поведение типа, используется для условно устаревших функций, таких как [`PyType_FromMetaclass()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_FromMetaclass).

Эта структура содержит несколько членов, которые вместо этого можно указать как [slots](https://python-all.ru/3.16/c-api/type.html#pyslot-type-slot-ids) для [`PyType_FromSlots()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_FromSlots), и массив записей слотов с более простой структурой.

#### `const char *name`

Соответствует [`Py_tp_name`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_name).

#### `int basicsize`

Если положительное, соответствует [`Py_tp_basicsize`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_basicsize).

Если отрицательное, соответствует [`Py_tp_extra_basicsize`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_extra_basicsize), установленному в абсолютное значение.

Изменено в версии 3.12: Ранее это поле не могло быть отрицательным.

#### `int itemsize`

Соответствует [`Py_tp_itemsize`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_itemsize).

#### `unsigned int flags`

Соответствует [`Py_tp_flags`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_flags).

#### `PyType_Slot *slots`

Массив структур [`PyType_Slot`](https://python-all.ru/3.16/c-api/type.html#c.PyType_Slot) (не [`PySlot`](https://python-all.ru/3.16/c-api/slots.html#c.PySlot)).

Завершается специальным значением слота `{0, NULL}`. Каждый идентификатор слота должен быть указан не более одного раза.

Keep old URL fragments working (see gh-97908)

#### `type PyType_Slot`

*Часть [Stable ABI](https://python-all.ru/3.16/c-api/stable.html#stable) (включая все члены).*

Структура, определяющая опциональную функциональность типа, используется для условно устаревших функций, таких как [`PyType_FromMetaclass()`](https://python-all.ru/3.16/c-api/type.html#c.PyType_FromMetaclass).

Обратите внимание, что массив `PyType_Slot` может быть включён в массив `PySlot` с помощью [`Py_tp_slots`](https://python-all.ru/3.16/c-api/type.html#c.Py_tp_slots), и наоборот с помощью [`Py_slot_subslots`](https://python-all.ru/3.16/c-api/slots.html#c.Py_slot_subslots).

Каждая структура `PyType_Slot` `tpslot` интерпретируется как следующая структура [`PySlot`](https://python-all.ru/3.16/c-api/slots.html#c.PySlot):

```c
(PySlot){
   .sl_id=tpslot.slot,
   .sl_flags=PySlot_INTPTR | sub_static,
   .sl_ptr=tpslot.func
}
```

где `sub_static` равно `PySlot_STATIC`, если слот требует флаг (например, для [`Py_tp_methods`](https://python-all.ru/3.16/c-api/typeobj.html#c.Py_tp_methods)), или если этот флаг присутствует в «родительском» слоте `Py_tp_slots` (если есть).

#### `int slot`

Соответствует [`PySlot.sl_id`](https://python-all.ru/3.16/c-api/slots.html#c.PySlot.sl_id).

#### `void *pfunc`

Соответствует [`PySlot.sl_ptr`](https://python-all.ru/3.16/c-api/slots.html#c.PySlot.sl_ptr).
