Spec-Zone.ru › Python 3.14

Структуры объектов типов

Пожалуй, одна из важнейших структур в системе объектов Python — структура, определяющая новый тип: структура PyTypeObject. Объекты типов можно обрабатывать с помощью любой из функций PyObject_* или PyType_*, но для большинства приложений Python они не предлагают ничего особенно интересного. Эти объекты лежат в основе поведения объектов, поэтому они очень важны для самого интерпретатора и для любого модуля расширения, реализующего новые типы.

Объекты типов довольно велики по сравнению с большинством стандартных типов. Их размер обусловлен тем, что каждый объект типа хранит большое количество значений, преимущественно указателей на функции C, каждый из которых реализует небольшую часть функциональности типа. Поля объекта типа подробно рассматриваются в этом разделе. Поля описаны в порядке их расположения в структуре.

Помимо следующей краткой справки, раздел Примеры даёт наглядное представление о значении и использовании PyTypeObject.

Краткая справка

«слоты tp»

Слот PyTypeObject [1]

Тип

специальные методы/атрибуты

Информация [2]

O

T

D

I

<R> tp_name

const char *

__name__

X

X

tp_basicsize

Py_ssize_t

X

X

X

tp_itemsize

Py_ssize_t

X

X

tp_dealloc

destructor

X

X

X

tp_vectorcall_offset

Py_ssize_t

X

X

(tp_getattr)

getattrfunc

__getattribute__, __getattr__

G

(tp_setattr)

setattrfunc

__setattr__, __delattr__

G

tp_as_async

PyAsyncMethods *

подслоты

%

tp_repr

reprfunc

__repr__

X

X

X

tp_as_number

PyNumberMethods *

подслоты

%

tp_as_sequence

PySequenceMethods *

подслоты

%

tp_as_mapping

PyMappingMethods *

подслоты

%

tp_hash

hashfunc

__hash__

X

G

tp_call

ternaryfunc

__call__

X

X

tp_str

reprfunc

__str__

X

X

tp_getattro

getattrofunc

__getattribute__, __getattr__

X

X

G

tp_setattro

setattrofunc

__setattr__, __delattr__

X

X

G

tp_as_buffer

PyBufferProcs *

подслоты

%

tp_flags

unsigned long

X

X

?

tp_doc

const char *

__doc__

X

X

tp_traverse

traverseproc

X

G

tp_clear

inquiry

X

G

tp_richcompare

richcmpfunc

__lt__, __le__, __eq__, __ne__, __gt__, __ge__

X

G

(tp_weaklistoffset)

Py_ssize_t

X

?

tp_iter

getiterfunc

__iter__

X

tp_iternext

iternextfunc

__next__

X

tp_methods

PyMethodDef []

X

X

tp_members

PyMemberDef []

X

tp_getset

PyGetSetDef []

X

X

tp_base

PyTypeObject *

__base__

X

tp_dict

PyObject *

__dict__

?

tp_descr_get

descrgetfunc

__get__

X

tp_descr_set

descrsetfunc

__set__, __delete__

X

(tp_dictoffset)

Py_ssize_t

X

?

tp_init

initproc

__init__

X

X

X

tp_alloc

allocfunc

X

?

?

tp_new

newfunc

__new__

X

X

?

?

tp_free

freefunc

X

X

?

?

tp_is_gc

inquiry

X

X

<tp_bases>

PyObject *

__bases__

~

<tp_mro>

PyObject *

__mro__

~

[tp_cache]

PyObject *

[tp_subclasses]

void *

__subclasses__

[tp_weaklist]

PyObject *

(tp_del)

destructor

[tp_version_tag]

unsigned int

tp_finalize

destructor

__del__

X

tp_vectorcall

vectorcallfunc

[tp_watched]

unsigned char

[1]

(): Имя слота в круглых скобках указывает на то, что он (фактически) устарел.

<>: Имена в угловых скобках изначально следует установить в NULL и считать доступными только для чтения.

[]: Имена в квадратных скобках предназначены только для внутреннего использования.

<R> (в качестве префикса) означает, что поле является обязательным (не должно быть NULL).

[2]

Столбцы:

“O”: устанавливается для PyBaseObject_Type

“T”: устанавливается для PyType_Type

“D”: значение по умолчанию (если слот установлен в NULL)

X - PyType_Ready sets this value if it is NULL
~ - PyType_Ready always sets this value (it should be NULL)
? - PyType_Ready may set this value depending on other slots

Also see the inheritance column ("I").

“I”: наследование

X - type slot is inherited via *PyType_Ready* if defined with a *NULL* value
% - the slots of the sub-struct are inherited individually
G - inherited, but only in combination with other slots; see the slot's description
? - it's complicated; see the slot's description

Обратите внимание, что некоторые слоты фактически наследуются через обычную цепочку поиска атрибутов.

подслоты

Слот

Тип

специальные методы

am_await

unaryfunc

__await__

am_aiter

unaryfunc

__aiter__

am_anext

unaryfunc

__anext__

am_send

sendfunc

nb_add

binaryfunc

__add__ __radd__

nb_inplace_add

binaryfunc

__iadd__

nb_subtract

binaryfunc

__sub__ __rsub__

nb_inplace_subtract

binaryfunc

__isub__

nb_multiply

binaryfunc

__mul__ __rmul__

nb_inplace_multiply

binaryfunc

__imul__

nb_remainder

binaryfunc

__mod__ __rmod__

nb_inplace_remainder

binaryfunc

__imod__

nb_divmod

binaryfunc

__divmod__ __rdivmod__

nb_power

ternaryfunc

__pow__ __rpow__

nb_inplace_power

ternaryfunc

__ipow__

nb_negative

unaryfunc

__neg__

nb_positive

unaryfunc

__pos__

nb_absolute

unaryfunc

__abs__

nb_bool

inquiry

__bool__

nb_invert

unaryfunc

__invert__

nb_lshift

binaryfunc

__lshift__ __rlshift__

nb_inplace_lshift

binaryfunc

__ilshift__

nb_rshift

binaryfunc

__rshift__ __rrshift__

nb_inplace_rshift

binaryfunc

__irshift__

nb_and

binaryfunc

__and__ __rand__

nb_inplace_and

binaryfunc

__iand__

nb_xor

binaryfunc

__xor__ __rxor__

nb_inplace_xor

binaryfunc

__ixor__

nb_or

binaryfunc

__or__ __ror__

nb_inplace_or

binaryfunc

__ior__

nb_int

unaryfunc

__int__

nb_reserved

void *

nb_float

unaryfunc

__float__

nb_floor_divide

binaryfunc

__floordiv__

nb_inplace_floor_divide

binaryfunc

__ifloordiv__

nb_true_divide

binaryfunc

__truediv__

nb_inplace_true_divide

binaryfunc

__itruediv__

nb_index

unaryfunc

__index__

nb_matrix_multiply

binaryfunc

__matmul__ __rmatmul__

nb_inplace_matrix_multiply

binaryfunc

__imatmul__

mp_length

lenfunc

__len__

mp_subscript

binaryfunc

__getitem__

mp_ass_subscript

objobjargproc

__setitem__, __delitem__

sq_length

lenfunc

__len__

sq_concat

binaryfunc

__add__

sq_repeat

ssizeargfunc

__mul__

sq_item

ssizeargfunc

__getitem__

sq_ass_item

ssizeobjargproc

__setitem__ __delitem__

sq_contains

objobjproc

__contains__

sq_inplace_concat

binaryfunc

__iadd__

sq_inplace_repeat

ssizeargfunc

__imul__

bf_getbuffer

getbufferproc()

__buffer__

bf_releasebuffer

releasebufferproc()

__release_buffer__

Определения типов слотов

определение типа

Типы параметров

Тип возвращаемого значения

allocfunc

PyObject *

destructor

PyObject *

void

freefunc

void *

void

traverseproc

int

newfunc

PyObject *

initproc

int

reprfunc

PyObject *

PyObject *

getattrfunc

PyObject *

setattrfunc

int

getattrofunc

PyObject *

setattrofunc

int

descrgetfunc

PyObject *

descrsetfunc

int

hashfunc

PyObject *

Py_hash_t

richcmpfunc

PyObject *

getiterfunc

PyObject *

PyObject *

iternextfunc

PyObject *

PyObject *

lenfunc

PyObject *

Py_ssize_t

getbufferproc

int

releasebufferproc

void

inquiry

PyObject *

int

unaryfunc

PyObject *

binaryfunc

PyObject *

ternaryfunc

PyObject *

ssizeargfunc

PyObject *

ssizeobjargproc

int

objobjproc

int

objobjargproc

int

Подробнее см. ниже: Определения типов слотов.

Определение PyTypeObject

Определение структуры PyTypeObject можно найти в Include/cpython/object.h. Для удобства здесь повторено приведённое там определение:

typedef struct _typeobject {
    PyObject_VAR_HEAD
    const char *tp_name; /* For printing, in format "<module>.<name>" */
    Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */

    /* Methods to implement standard operations */

    destructor tp_dealloc;
    Py_ssize_t tp_vectorcall_offset;
    getattrfunc tp_getattr;
    setattrfunc tp_setattr;
    PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)
                                    or tp_reserved (Python 3) */
    reprfunc tp_repr;

    /* Method suites for standard classes */

    PyNumberMethods *tp_as_number;
    PySequenceMethods *tp_as_sequence;
    PyMappingMethods *tp_as_mapping;

    /* More standard operations (here for binary compatibility) */

    hashfunc tp_hash;
    ternaryfunc tp_call;
    reprfunc tp_str;
    getattrofunc tp_getattro;
    setattrofunc tp_setattro;

    /* Functions to access object as input/output buffer */
    PyBufferProcs *tp_as_buffer;

    /* Flags to define presence of optional/expanded features */
    unsigned long tp_flags;

    const char *tp_doc; /* Documentation string */

    /* Assigned meaning in release 2.0 */
    /* call function for all accessible objects */
    traverseproc tp_traverse;

    /* delete references to contained objects */
    inquiry tp_clear;

    /* Assigned meaning in release 2.1 */
    /* rich comparisons */
    richcmpfunc tp_richcompare;

    /* weak reference enabler */
    Py_ssize_t tp_weaklistoffset;

    /* Iterators */
    getiterfunc tp_iter;
    iternextfunc tp_iternext;

    /* Attribute descriptor and subclassing stuff */
    PyMethodDef *tp_methods;
    PyMemberDef *tp_members;
    PyGetSetDef *tp_getset;
    // Strong reference on a heap type, borrowed reference on a static type
    PyTypeObject *tp_base;
    PyObject *tp_dict;
    descrgetfunc tp_descr_get;
    descrsetfunc tp_descr_set;
    Py_ssize_t tp_dictoffset;
    initproc tp_init;
    allocfunc tp_alloc;
    newfunc tp_new;
    freefunc tp_free; /* Low-level free-memory routine */
    inquiry tp_is_gc; /* For PyObject_IS_GC */
    PyObject *tp_bases;
    PyObject *tp_mro; /* method resolution order */
    PyObject *tp_cache; /* no longer used */
    void *tp_subclasses;  /* for static builtin types this is an index */
    PyObject *tp_weaklist; /* not used for static builtin types */
    destructor tp_del;

    /* Type attribute cache version tag. Added in version 2.6.
     * If zero, the cache is invalid and must be initialized.
     */
    unsigned int tp_version_tag;

    destructor tp_finalize;
    vectorcallfunc tp_vectorcall;

    /* bitset of which type-watchers care about this type */
    unsigned char tp_watched;

    /* Number of tp_version_tag values used.
     * Set to _Py_ATTR_CACHE_UNUSED if the attribute cache is
     * disabled for this type (e.g. due to custom MRO entries).
     * Otherwise, limited to MAX_VERSIONS_PER_CLASS (defined elsewhere).
     */
    uint16_t tp_versions_used;
} PyTypeObject;

Слоты PyObject

Структура объекта типа расширяет структуру PyVarObject. Поле ob_size используется для динамических типов (создаваемых с помощью type_new(), обычно вызываемого из инструкции class). Обратите внимание, что PyType_Type (метатип) инициализирует tp_itemsize, а значит, его экземпляры (то есть объекты типов) должны иметь поле ob_size.

PyObject.ob_refcnt

Счётчик ссылок объекта типа инициализируется значением 1 макросом PyObject_HEAD_INIT. Обратите внимание, что для статически размещённых объектов типов экземпляры типа (объекты, у которых ob_type указывает обратно на тип) не учитываются как ссылки. Но для динамически размещённых объектов типов экземпляры учитываются как ссылки.

Наследование:

Это поле не наследуется подклассами.

PyObject.ob_type

Это тип данного типа, другими словами, его метатип. Он инициализируется аргументом макроса PyObject_HEAD_INIT, и обычно его значение должно быть &PyType_Type. Однако для динамически загружаемых модулей расширения, которые должны работать в Windows (как минимум), компилятор сообщает, что это недопустимый инициализатор. Поэтому принято передавать NULL макросу PyObject_HEAD_INIT и явно инициализировать это поле в начале функции инициализации модуля, прежде чем выполнять какие-либо другие действия. Обычно это делается так:

Foo_Type.ob_type = &PyType_Type;

Это следует сделать до создания экземпляров типа. PyType_Ready() проверяет, равно ли ob_type значению NULL, и если да, инициализирует его значением поля ob_type базового класса. PyType_Ready() не изменит это поле, если оно не равно нулю.

Наследование:

Это поле наследуется подклассами.

Слоты PyVarObject

PyVarObject.ob_size

Для статически размещённых объектов типов этому полю следует присвоить ноль. Для динамически размещённых объектов типов это поле имеет особое внутреннее значение.

Доступ к этому полю следует осуществлять с помощью макроса Py_SIZE().

Наследование:

Это поле не наследуется подклассами.

Слоты PyTypeObject

Для каждого слота есть раздел с описанием наследования. Если PyType_Ready() может устанавливать значение, когда поле установлено в NULL, то будет также раздел «По умолчанию». (Обратите внимание, что многие поля, установленные в PyBaseObject_Type и PyType_Type, фактически действуют как значения по умолчанию.)

const char *PyTypeObject.tp_name

Указатель на завершающуюся нулевым байтом строку, содержащую имя типа. Для типов, доступных как глобальные переменные модуля, строка должна содержать полное имя модуля, за которым следует точка, а затем имя типа; для встроенных типов достаточно указать только имя типа. Если модуль является подмодулем пакета, полное имя пакета входит в полное имя модуля. Например, тип с именем T, определённый в модуле M во вложенном пакете Q пакета P, должен иметь инициализатор tp_name "P.Q.M.T".

Для динамически выделяемых объектов типа здесь следует указывать только имя типа, а имя модуля должно быть явно сохранено в словаре типа как значение для ключа '__module__'.

Для статически выделяемых объектов типа поле tp_name должно содержать точку. Всё, что находится до последней точки, становится доступным как атрибут __module__, а всё, что находится после последней точки, — как атрибут __name__.

Если точка отсутствует, всё поле tp_name становится доступным как атрибут __name__, а атрибут __module__ не определён (если только он явно не задан в словаре, как описано выше). Это означает, что ваш тип невозможно будет сериализовать с помощью pickle. Кроме того, он не будет указан в документации модулей, созданной с помощью pydoc.

Это поле не должно быть NULL. Это единственное обязательное поле в PyTypeObject() (помимо возможного tp_itemsize).

Наследование:

Это поле не наследуется подклассами.

Py_ssize_t PyTypeObject.tp_basicsize
Py_ssize_t PyTypeObject.tp_itemsize

Эти поля позволяют вычислить размер экземпляров типа в байтах.

Существует два вида типов: у типов с экземплярами фиксированной длины поле tp_itemsize равно нулю, а у типов с экземплярами переменной длины поле tp_itemsize не равно нулю. Все экземпляры типа с экземплярами фиксированной длины имеют одинаковый размер, заданный в tp_basicsize. (Исключения из этого правила можно создавать с помощью PyUnstable_Object_GC_NewWithExtraData().)

Экземпляры типа с экземплярами переменной длины должны иметь поле ob_size, а размер экземпляра равен tp_basicsize плюс N, умноженное на tp_itemsize, где N — «длина» объекта.

Такие функции, как PyObject_NewVar(), принимают значение N в качестве аргумента и сохраняют его в поле экземпляра ob_size. Обратите внимание, что впоследствии поле ob_size может использоваться для других целей. Например, экземпляры int используют биты ob_size способом, определяемым реализацией; доступ к базовому хранилищу и его размеру следует получать с помощью PyLong_Export().

Примечание

Доступ к полю ob_size следует осуществлять с помощью макросов Py_SIZE() и Py_SET_SIZE().

Кроме того, наличие поля ob_size в структуре экземпляра не означает, что структура экземпляра имеет переменную длину. Например, тип list имеет экземпляры фиксированной длины, однако в этих экземплярах есть поле ob_size. (Как и в случае с int, не обращайтесь напрямую к полю ob_size списков. Вместо этого вызывайте PyList_Size().)

Поле tp_basicsize включает размер, необходимый для данных типа, указанного в tp_base, а также любые дополнительные данные, необходимые каждому экземпляру.

Правильный способ задать tp_basicsize — использовать оператор sizeof для структуры, применяемой для объявления структуры экземпляра. Эта структура должна включать структуру, используемую для объявления базового типа. Иными словами, tp_basicsize должно быть больше или равно tp_basicsize базового типа.

Поскольку каждый тип является подтипом object, эта структура должна включать PyObject или PyVarObject (в зависимости от того, следует ли включать ob_size). Обычно они определяются макросами PyObject_HEAD или PyObject_VAR_HEAD соответственно.

Базовый размер не включает размер заголовка GC, поскольку этот заголовок не является частью PyObject_HEAD.

Если структура, используемая для объявления базового типа, неизвестна, см. PyType_Spec.basicsize и PyType_FromMetaclass().

Примечания о выравнивании:

  • tp_basicsize должно быть кратно _Alignof(PyObject). При использовании sizeof для struct, включающего PyObject_HEAD, как и рекомендуется, компилятор обеспечивает это условие. Если C struct не используется либо используются расширения компилятора, такие как __attribute__((packed)), обеспечить это условие должны вы.
  • Если для элементов переменной части требуется определённое выравнивание, tp_basicsize и tp_itemsize должны быть кратны этому выравниванию. Например, если переменная часть типа хранит double, вы должны обеспечить, чтобы оба поля были кратны _Alignof(double).

Наследование:

Подтипы наследуют эти поля независимо друг от друга. (То есть, если значение поля равно нулю, PyType_Ready() скопирует значение из базового типа, указывая, что экземплярам не требуется дополнительное хранилище.)

Если значение tp_itemsize базового типа не равно нулю, обычно небезопасно задавать tp_itemsize другое ненулевое значение в подтипе (хотя это зависит от реализации базового типа).

destructor PyTypeObject.tp_dealloc

Соответствующий идентификатор слота Py_tp_dealloc входит в стабильный ABI.

Указатель на функцию-деструктор экземпляра. Сигнатура функции:

void tp_dealloc(PyObject *self);

Функция-деструктор должна удалить все ссылки, которыми владеет экземпляр (например, вызвать Py_CLEAR()), освободить все буферы памяти, принадлежащие экземпляру, и вызвать функцию tp_free типа для освобождения самого объекта.

Если вы можете вызывать функции, которые могут установить индикатор ошибки, необходимо использовать PyErr_GetRaisedException() и PyErr_SetRaisedException(), чтобы не затереть уже установленный индикатор ошибки (освобождение могло произойти при обработке другой ошибки):

static void
foo_dealloc(foo_object *self)
{
    PyObject *et, *ev, *etb;
    PyObject *exc = PyErr_GetRaisedException();
    ...
    PyErr_SetRaisedException(exc);
}

Сам обработчик освобождения не должен возбуждать исключение; при возникновении ошибки он должен вызвать PyErr_FormatUnraisable(), чтобы записать в журнал (и очистить) необрабатываемое исключение.

Нет гарантий относительно того, когда объект будет уничтожен, за исключением следующих:

  • Python уничтожит объект немедленно или спустя некоторое время после удаления последней ссылки на него, если только его финализатор (tp_finalize) впоследствии не воскресит объект.
  • Объект не будет уничтожен во время автоматической финализации (tp_finalize) или автоматической очистки (tp_clear).

В настоящее время CPython уничтожает объект непосредственно из Py_DECREF(), когда новое значение счётчика ссылок равно нулю, однако в будущей версии это может измениться.

Рекомендуется вызывать PyObject_CallFinalizerFromDealloc() в начале tp_dealloc, чтобы гарантировать финализацию объекта перед его уничтожением.

Если тип поддерживает сборку мусора (установлен флаг Py_TPFLAGS_HAVE_GC), перед очисткой полей-членов деструктор должен вызвать PyObject_GC_UnTrack().

Допускается вызывать tp_clear из tp_dealloc, чтобы избежать дублирования кода и гарантировать очистку объекта перед его уничтожением. Учтите, что tp_clear уже могла быть вызвана.

Если тип размещён в куче (Py_TPFLAGS_HEAPTYPE), после вызова деаллокатора типа деаллокатор должен освободить принадлежащую ему ссылку на объект типа (с помощью Py_DECREF()). См. пример кода ниже:

static void
foo_dealloc(PyObject *op)
{
   foo_object *self = (foo_object *) op;
   PyObject_GC_UnTrack(self);
   Py_CLEAR(self->ref);
   Py_TYPE(self)->tp_free(self);
}

tp_dealloc должна оставить состояние исключения неизменным. Если ей необходимо вызвать функцию, которая может возбудить исключение, сначала следует сохранить состояние исключения, а затем восстановить его (после записи любых исключений в журнал с помощью PyErr_WriteUnraisable()).

Пример:

static void
foo_dealloc(PyObject *self)
{
    PyObject *exc = PyErr_GetRaisedException();

    if (PyObject_CallFinalizerFromDealloc(self) < 0) {
        // self was resurrected.
        goto done;
    }

    PyTypeObject *tp = Py_TYPE(self);

    if (tp->tp_flags & Py_TPFLAGS_HAVE_GC) {
        PyObject_GC_UnTrack(self);
    }

    // Optional, but convenient to avoid code duplication.
    if (tp->tp_clear && tp->tp_clear(self) < 0) {
        PyErr_WriteUnraisable(self);
    }

    // Any additional destruction goes here.

    tp->tp_free(self);
    self = NULL;  // In case PyErr_WriteUnraisable() is called below.

    if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE) {
        Py_CLEAR(tp);
    }

done:
    // Optional, if something was called that might have raised an
    // exception.
    if (PyErr_Occurred()) {
        PyErr_WriteUnraisable(self);
    }
    PyErr_SetRaisedException(exc);
}

tp_dealloc может быть вызвана из любого потока Python, а не только из потока, создавшего объект (если объект становится частью цикла ссылок, этот цикл может быть собран сборщиком мусора в любом потоке). Для вызовов Python API это не проблема, поскольку поток, в котором вызывается tp_dealloc, имеет присоединённое состояние потока. Однако если уничтожаемый объект, в свою очередь, уничтожает объекты из другой библиотеки C, необходимо убедиться, что уничтожение этих объектов в потоке, вызвавшем tp_dealloc, не нарушит предположений библиотеки.

Наследование:

Это поле наследуется подклассами.

См. также

Подробные сведения о связи этого слота с другими слотами см. в разделе Жизненный цикл объекта.

Py_ssize_t PyTypeObject.tp_vectorcall_offset

Необязательное смещение до функции для отдельного экземпляра, реализующей вызов объекта с использованием протокола vectorcall — более эффективной альтернативы простому tp_call.

Это поле используется только в том случае, если установлен флаг Py_TPFLAGS_HAVE_VECTORCALL. Если он установлен, поле должно содержать положительное целое число — смещение в экземпляре указателя vectorcallfunc.

Указатель vectorcallfunc может быть NULL; в этом случае экземпляр ведёт себя так, как если бы Py_TPFLAGS_HAVE_VECTORCALL не был установлен: при вызове экземпляра используется tp_call.

Любой класс, задающий Py_TPFLAGS_HAVE_VECTORCALL, должен также задавать tp_call и обеспечивать согласованность его поведения с функцией vectorcallfunc. Для этого можно присвоить tp_call значение PyVectorcall_Call().

Изменено в версии 3.8: До версии 3.8 этот слот назывался tp_print. В Python 2.x он использовался для вывода в файл. В Python 3.0–3.7 он не использовался.

Изменено в версии 3.12: До версии 3.12 не рекомендовалось реализовывать протокол vectorcall для изменяемых типов в куче. Когда пользователь задаёт __call__ в коде Python, обновляется только tp_call, что, вероятно, приводит к его несогласованности с функцией vectorcall. Начиная с версии 3.12, задание __call__ отключает оптимизацию vectorcall, сбрасывая флаг Py_TPFLAGS_HAVE_VECTORCALL.

Наследование:

Это поле всегда наследуется. Однако флаг Py_TPFLAGS_HAVE_VECTORCALL наследуется не всегда. Если он не установлен, подкласс не будет использовать vectorcall, за исключением случаев явного вызова PyVectorcall_Call().

getattrfunc PyTypeObject.tp_getattr

Соответствующий идентификатор слота Py_tp_getattr входит в стабильный ABI.

Необязательный указатель на функцию получения атрибута по строке.

Это поле объявлено устаревшим. Если оно задано, оно должно указывать на функцию, действующую так же, как функция tp_getattro, но принимающую строку C вместо строкового объекта Python для указания имени атрибута.

Наследование:

Группа: tp_getattr, tp_getattro

Это поле наследуется подклассами вместе с tp_getattro: подкласс наследует и tp_getattr, и tp_getattro от базового типа, если tp_getattr и tp_getattro подкласса имеют значение NULL.

setattrfunc PyTypeObject.tp_setattr

Соответствующий идентификатор слота Py_tp_setattr входит в стабильный ABI.

Необязательный указатель на функцию установки и удаления атрибутов.

Это поле объявлено устаревшим. Если оно задано, оно должно указывать на функцию, действующую так же, как функция tp_setattro, но принимающую строку C вместо строкового объекта Python для указания имени атрибута.

Наследование:

Группа: tp_setattr, tp_setattro

Это поле наследуется подклассами вместе с tp_setattro: подкласс наследует и tp_setattr, и tp_setattro от базового типа, если tp_setattr и tp_setattro подкласса имеют значение NULL.

PyAsyncMethods *PyTypeObject.tp_as_async

Указатель на дополнительную структуру с полями, относящимися только к объектам, которые реализуют на уровне C протоколы ожидаемых объектов и асинхронных итераторов. Подробности см. в разделе Структуры асинхронных объектов.

Добавлено в версии 3.5: Ранее называлось tp_compare и tp_reserved.

Наследование:

Поле tp_as_async не наследуется, но содержащиеся в нём поля наследуются по отдельности.

reprfunc PyTypeObject.tp_repr

Соответствующий идентификатор слота Py_tp_repr входит в стабильный ABI.

Необязательный указатель на функцию, реализующую встроенную функцию repr().

Сигнатура совпадает с сигнатурой PyObject_Repr():

PyObject *tp_repr(PyObject *self);

Функция должна возвращать строку или объект Unicode. В идеале эта функция должна возвращать строку, передача которой в eval() в подходящем окружении возвращает объект с тем же значением. Если это невозможно, функция должна возвращать строку, начинающуюся с '<' и заканчивающуюся '>', по которой можно определить тип и значение объекта.

Наследование:

Это поле наследуется подклассами.

Значение по умолчанию:

Если это поле не задано, возвращается строка вида <%s object at %p>, где %s заменяется именем типа, а %p — адресом объекта в памяти.

PyNumberMethods *PyTypeObject.tp_as_number

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

Наследование:

Поле tp_as_number не наследуется, но содержащиеся в нём поля наследуются по отдельности.

PySequenceMethods *PyTypeObject.tp_as_sequence

Указатель на дополнительную структуру, содержащую поля, относящиеся только к объектам, реализующим протокол последовательностей. Эти поля описаны в разделе Структуры объектов-последовательностей.

Наследование:

Поле tp_as_sequence не наследуется, но содержащиеся в нём поля наследуются по отдельности.

PyMappingMethods *PyTypeObject.tp_as_mapping

Указатель на дополнительную структуру, содержащую поля, относящиеся только к объектам, реализующим протокол отображений. Эти поля описаны в разделе Структуры объектов-отображений.

Наследование:

Поле tp_as_mapping не наследуется, но содержащиеся в нём поля наследуются по отдельности.

hashfunc PyTypeObject.tp_hash

Соответствующий идентификатор слота Py_tp_hash входит в состав стабильного ABI.

Необязательный указатель на функцию, реализующую встроенную функцию hash().

Сигнатура совпадает с сигнатурой PyObject_Hash():

Py_hash_t tp_hash(PyObject *);

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

Если это поле не задано (и не задано tp_richcompare), попытка вычислить хеш объекта вызывает исключение TypeError. Это равносильно присваиванию ему значения PyObject_HashNotImplemented().

Этому полю можно явно присвоить значение PyObject_HashNotImplemented(), чтобы запретить наследование метода хеширования от родительского типа. На уровне Python это интерпретируется как эквивалент __hash__ = None, в результате чего isinstance(o, collections.Hashable) корректно возвращает False. Обратите внимание, что верно и обратное: присваивание __hash__ = None классу на уровне Python приведёт к тому, что слоту tp_hash будет присвоено значение PyObject_HashNotImplemented().

Наследование:

Группа: tp_hash, tp_richcompare

Это поле наследуется подтипами вместе с tp_richcompare: подтип наследует оба поля — tp_richcompare и tp_hash, если tp_richcompare и tp_hash подтипа равны NULL.

По умолчанию:

PyBaseObject_Type использует PyObject_GenericHash().

ternaryfunc PyTypeObject.tp_call

Соответствующий идентификатор слота Py_tp_call входит в состав стабильного ABI.

Необязательный указатель на функцию, реализующую вызов объекта. Если объект не является вызываемым, здесь должно быть NULL. Сигнатура совпадает с сигнатурой PyObject_Call():

PyObject *tp_call(PyObject *self, PyObject *args, PyObject *kwargs);

Наследование:

Это поле наследуется подтипами.

reprfunc PyTypeObject.tp_str

Соответствующий идентификатор слота Py_tp_str входит в состав стабильного ABI.

Необязательный указатель на функцию, реализующую встроенную операцию str(). (Обратите внимание, что теперь str — это тип, а str() вызывает конструктор этого типа. Этот конструктор вызывает PyObject_Str() для выполнения фактической работы, а PyObject_Str() вызывает этот обработчик.)

Сигнатура совпадает с сигнатурой PyObject_Str():

PyObject *tp_str(PyObject *self);

Функция должна возвращать строку или объект Unicode. Она должна возвращать «понятное» строковое представление объекта, поскольку это представление используется, помимо прочего, функцией print().

Наследование:

Это поле наследуется подтипами.

По умолчанию:

Если это поле не задано, для возврата строкового представления вызывается PyObject_Repr().

getattrofunc PyTypeObject.tp_getattro

Соответствующий идентификатор слота Py_tp_getattro входит в состав стабильного ABI.

Необязательный указатель на функцию получения атрибута.

Сигнатура совпадает с сигнатурой PyObject_GetAttr():

PyObject *tp_getattro(PyObject *self, PyObject *attr);

Обычно удобно присвоить этому полю значение PyObject_GenericGetAttr(), реализующее стандартный способ поиска атрибутов объекта.

Наследование:

Группа: tp_getattr, tp_getattro

Это поле наследуется подтипами вместе с tp_getattr: подтип наследует оба поля — tp_getattr и tp_getattro — от базового типа, если tp_getattr и tp_getattro подтипа равны NULL.

По умолчанию:

PyBaseObject_Type использует PyObject_GenericGetAttr().

setattrofunc PyTypeObject.tp_setattro

Соответствующий идентификатор слота Py_tp_setattro входит в состав стабильного ABI.

Необязательный указатель на функцию установки и удаления атрибутов.

Сигнатура совпадает с сигнатурой PyObject_SetAttr():

int tp_setattro(PyObject *self, PyObject *attr, PyObject *value);

Кроме того, должна поддерживаться передача NULL в качестве значения value для удаления атрибута. Обычно удобно присвоить этому полю значение PyObject_GenericSetAttr(), реализующее стандартный способ установки атрибутов объекта.

Наследование:

Группа: tp_setattr, tp_setattro

Это поле наследуется подтипами вместе с tp_setattr: подтип наследует оба поля — tp_setattr и tp_setattro — от базового типа, если tp_setattr и tp_setattro подтипа равны NULL.

По умолчанию:

PyBaseObject_Type использует PyObject_GenericSetAttr().

PyBufferProcs *PyTypeObject.tp_as_buffer

Указатель на дополнительную структуру, содержащую поля, относящиеся только к объектам, реализующим буферный интерфейс. Эти поля описаны в разделе Структуры буферных объектов.

Наследование:

Поле tp_as_buffer не наследуется, но содержащиеся в нём поля наследуются по отдельности.

unsigned long PyTypeObject.tp_flags

Это поле представляет собой битовую маску различных флагов. Некоторые флаги указывают на варианты семантики в определённых ситуациях; другие используются для указания того, что определённые поля объекта типа (или в структурах расширения, на которые ссылаются через tp_as_number, tp_as_sequence, tp_as_mapping и tp_as_buffer), которые исторически присутствовали не всегда, являются допустимыми; если соответствующий бит флага сброшен, поля типа, за доступ к которым он отвечает, нельзя использовать, и вместо этого их следует считать имеющими нулевое или NULL значение.

Наследование:

Наследование этого поля устроено сложно. Большинство битов флагов наследуются по отдельности, то есть если бит флага установлен у базового типа, подтип наследует этот бит. Биты флагов, относящиеся к структурам расширения, наследуются строго вместе со структурой расширения: значение бита флага базового типа копируется в подтип вместе с указателем на структуру расширения. Бит флага Py_TPFLAGS_HAVE_GC наследуется вместе с полями tp_traverse и tp_clear, то есть если бит флага Py_TPFLAGS_HAVE_GC сброшен у подтипа, а поля tp_traverse и tp_clear у подтипа существуют и имеют значения NULL.

Значение по умолчанию:

PyBaseObject_Type использует Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE.

Битовые маски:

В настоящее время определены следующие битовые маски; их можно объединять оператором |, чтобы сформировать значение поля tp_flags. Макрос PyType_HasFeature() принимает тип и значение флагов — tp и f — и проверяет, является ли tp->tp_flags & f ненулевым.

Py_TPFLAGS_HEAPTYPE

Этот бит устанавливается, когда сам объект типа выделен в куче, например, для типов, созданных динамически с помощью PyType_FromSpec(). В этом случае поле ob_type его экземпляров считается ссылкой на тип, и при создании нового экземпляра для объекта типа выполняется INCREF, а при уничтожении экземпляра — DECREF (это не относится к экземплярам подтипов; INCREF или DECREF выполняется только для типа, на который ссылается ob_type экземпляра). Для типов в куче также следует поддерживать сборку мусора, поскольку они могут образовывать цикл ссылок с собственным объектом модуля.

Наследование:

???

Py_TPFLAGS_BASETYPE
Часть стабильного ABI.

Этот бит устанавливается, если тип можно использовать как базовый тип другого типа. Если этот бит сброшен, от типа нельзя создавать подтипы (аналогично классу «final» в Java).

Наследование:

???

Py_TPFLAGS_READY

Этот бит устанавливается, когда объект типа полностью инициализирован функцией PyType_Ready().

Наследование:

???

Py_TPFLAGS_READYING

Этот бит устанавливается, пока PyType_Ready() выполняет инициализацию объекта типа.

Наследование:

???

Py_TPFLAGS_HAVE_GC
Часть стабильного ABI.

Этот бит устанавливается, если объект поддерживает сборку мусора. Если этот бит установлен, память для новых экземпляров (см. tp_alloc) должна выделяться с помощью PyObject_GC_New или PyType_GenericAlloc(), а освобождаться (см. tp_free) с помощью PyObject_GC_Del(). Дополнительные сведения приведены в разделе Поддержка циклической сборки мусора.

Наследование:

Группа: Py_TPFLAGS_HAVE_GC, tp_traverse, tp_clear

Бит флага Py_TPFLAGS_HAVE_GC наследуется вместе с полями tp_traverse и tp_clear, то есть если бит флага Py_TPFLAGS_HAVE_GC сброшен у подтипа, а поля tp_traverse и tp_clear у подтипа существуют и имеют значения NULL.

Py_TPFLAGS_DEFAULT
Часть стабильного ABI.

Это битовая маска всех битов, относящихся к наличию определённых полей в объекте типа и его структурах расширения. В настоящее время она включает следующие биты: Py_TPFLAGS_HAVE_STACKLESS_EXTENSION.

Наследование:

???

Py_TPFLAGS_METHOD_DESCRIPTOR
Часть стабильного ABI начиная с версии 3.8.

Этот бит указывает, что объекты ведут себя как несвязанные методы.

Если этот флаг установлен для type(meth), то:

  • meth.__get__(obj, cls)(*args, **kwds) (при условии, что obj не равно None) должно быть эквивалентно meth(obj, *args, **kwds).
  • meth.__get__(None, cls)(*args, **kwds) должно быть эквивалентно meth(*args, **kwds).

Этот флаг включает оптимизацию для типичных вызовов методов, таких как obj.meth(): она позволяет избежать создания временного объекта «связанного метода» для obj.meth.

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

Наследование:

Этот флаг никогда не наследуется типами, у которых не установлен флаг Py_TPFLAGS_IMMUTABLETYPE. Для типов расширения он наследуется при наследовании tp_descr_get.

Py_TPFLAGS_MANAGED_DICT

Этот бит указывает, что у экземпляров класса есть атрибут __dict__, а память для словаря управляется виртуальной машиной.

Если установлен этот флаг, следует также установить Py_TPFLAGS_HAVE_GC.

Функция обхода типа должна вызывать PyObject_VisitManagedDict(), а его функция очистки должна вызывать PyObject_ClearManagedDict().

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

Наследование:

Этот флаг наследуется, если только в суперклассе не задано поле tp_dictoffset.

Py_TPFLAGS_MANAGED_WEAKREF

Этот бит указывает, что на экземпляры класса должны быть возможны слабые ссылки.

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

Наследование:

Этот флаг наследуется, если только в суперклассе не задано поле tp_weaklistoffset.

Py_TPFLAGS_ITEMS_AT_END
Часть стабильного ABI начиная с версии 3.12.

Можно использовать только с типами переменного размера, то есть с типами, у которых tp_itemsize не равно нулю.

Указывает, что часть экземпляра этого типа переменного размера находится в конце области памяти экземпляра со смещением Py_TYPE(obj)->tp_basicsize (которое может отличаться для каждого подкласса).

При установке этого флага убедитесь, что все суперклассы используют такую же схему размещения в памяти или не имеют переменного размера. Python это не проверяет.

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

Наследование:

Этот флаг наследуется.

Py_TPFLAGS_LONG_SUBCLASS
Py_TPFLAGS_LIST_SUBCLASS
Py_TPFLAGS_TUPLE_SUBCLASS
Py_TPFLAGS_BYTES_SUBCLASS
Py_TPFLAGS_UNICODE_SUBCLASS
Py_TPFLAGS_DICT_SUBCLASS
Py_TPFLAGS_BASE_EXC_SUBCLASS
Py_TPFLAGS_TYPE_SUBCLASS

Такие функции, как PyLong_Check(), вызывают PyType_FastSubclass() с одним из этих флагов, чтобы быстро определить, является ли тип подклассом встроенного типа; такие специализированные проверки выполняются быстрее, чем общая проверка, например PyObject_IsInstance(). Пользовательские типы, наследующие встроенные типы, должны иметь соответствующим образом установленное поле tp_flags, иначе код, взаимодействующий с такими типами, будет вести себя по-разному в зависимости от используемой проверки.

Py_TPFLAGS_HAVE_FINALIZE

Этот бит устанавливается, когда слот tp_finalize присутствует в структуре типа.

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

Устарело с версии 3.8: Этот флаг больше не нужен, поскольку интерпретатор предполагает, что слот tp_finalize всегда присутствует в структуре типа.

Py_TPFLAGS_HAVE_VECTORCALL
Входит в Стабильный ABI начиная с версии 3.12.

Этот бит устанавливается, когда класс реализует протокол vectorcall. Подробности см. в tp_vectorcall_offset.

Наследование:

Этот бит наследуется, если также наследуется tp_call.

Добавлено в версии 3.8: как _Py_TPFLAGS_HAVE_VECTORCALL

Изменено в версии 3.9: Переименовано в текущее имя без начального символа подчёркивания. Старое предварительное имя имеет статус нестрого устаревшего.

Изменено в версии 3.12: Теперь этот флаг удаляется у класса, если его метод __call__() переназначается.

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

Py_TPFLAGS_IMMUTABLETYPE

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

PyType_Ready() автоматически устанавливает этот флаг для статических типов.

Наследование:

Этот флаг не наследуется.

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

Py_TPFLAGS_DISALLOW_INSTANTIATION

Запрещает создание экземпляров типа: установите tp_new в NULL и не создавайте ключ __new__ в словаре типа.

Флаг необходимо установить до создания типа, а не после. Например, его нужно установить до вызова PyType_Ready() для типа.

Флаг автоматически устанавливается для статических типов, если tp_base равен NULL или &PyBaseObject_Type, а tp_new равен NULL.

Наследование:

Этот флаг не наследуется. Однако экземпляры подклассов нельзя будет создавать, если только для них не задан ненулевой tp_new (что возможно только через C API).

Примечание

Чтобы запретить создание экземпляров самого класса, но разрешить создавать экземпляры его подклассов (например, для абстрактного базового класса), не используйте этот флаг. Вместо этого настройте tp_new так, чтобы он успешно выполнялся только для подклассов.

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

Py_TPFLAGS_MAPPING

Этот бит указывает, что экземпляры класса могут соответствовать шаблонам отображения, когда используются в качестве проверяемого объекта в блоке match. Он автоматически устанавливается при регистрации или создании подкласса collections.abc.Mapping и сбрасывается при регистрации collections.abc.Sequence.

Примечание

Py_TPFLAGS_MAPPING и Py_TPFLAGS_SEQUENCE взаимоисключающие; одновременное включение обоих флагов является ошибкой.

Наследование:

Этот флаг наследуется типами, у которых ещё не установлен Py_TPFLAGS_SEQUENCE.

См. также

PEP 634 — Структурное сопоставление с шаблоном: спецификация

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

Py_TPFLAGS_SEQUENCE

Этот бит указывает, что экземпляры класса могут соответствовать шаблонам последовательностей, когда используются в качестве проверяемого объекта в блоке match. Он автоматически устанавливается при регистрации или создании подкласса collections.abc.Sequence и сбрасывается при регистрации collections.abc.Mapping.

Примечание

Py_TPFLAGS_MAPPING и Py_TPFLAGS_SEQUENCE взаимоисключающие; одновременное включение обоих флагов является ошибкой.

Наследование:

Этот флаг наследуется типами, у которых ещё не установлен Py_TPFLAGS_MAPPING.

См. также

PEP 634 — Структурное сопоставление с шаблоном: спецификация

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

Py_TPFLAGS_VALID_VERSION_TAG

Внутренний флаг. Не устанавливайте и не сбрасывайте его. Чтобы сообщить об изменении класса, вызовите PyType_Modified()

Предупреждение

Этот флаг присутствует в заголовочных файлах, но использовать его не следует. Он будет удалён в одной из будущих версий CPython

Py_TPFLAGS_HAVE_VERSION_TAG

Этот макрос ничего не делает. Ранее он указывал, что поле tp_version_tag доступно и инициализировано.

Нестрого устарел с версии 3.13.

Py_TPFLAGS_INLINE_VALUES

Этот бит указывает, что экземпляры данного типа будут иметь массив «встроенных значений» (содержащий атрибуты объекта), размещённый непосредственно после конца объекта.

Для этого должен быть установлен Py_TPFLAGS_HAVE_GC.

Наследование:

Этот флаг не наследуется.

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

Py_TPFLAGS_IS_ABSTRACT

Этот бит указывает, что тип является абстрактным и поэтому не может быть инстанцирован.

Наследование:

Этот флаг не наследуется.

См. также

abc

Py_TPFLAGS_HAVE_STACKLESS_EXTENSION

Внутренний флаг. Не устанавливайте и не сбрасывайте его. Ранее это был зарезервированный флаг для использования в Stackless Python.

Предупреждение

Этот флаг присутствует в заголовочных файлах, но использовать его не следует. Он может быть удалён в одной из будущих версий CPython.

const char *PyTypeObject.tp_doc

Соответствующий идентификатор слота Py_tp_doc входит в Стабильный ABI.

Необязательный указатель на завершаемую NUL C-строку с документацией для этого объекта типа. Она доступна как атрибут __doc__ типа и его экземпляров.

Наследование:

Это поле не наследуется подклассами.

traverseproc PyTypeObject.tp_traverse

Соответствующий идентификатор слота Py_tp_traverse входит в стабильный ABI.

Необязательный указатель на функцию обхода для сборщика мусора. Он используется, только если установлен бит флага Py_TPFLAGS_HAVE_GC. Сигнатура:

int tp_traverse(PyObject *self, visitproc visit, void *arg);

Дополнительную информацию о механизме сборки мусора Python можно найти в разделе Поддержка циклической сборки мусора.

Указатель tp_traverse используется сборщиком мусора для обнаружения циклических ссылок. Типичная реализация функции tp_traverse просто вызывает Py_VISIT() для каждого члена экземпляра, который является объектом Python и принадлежит этому экземпляру. Например, это функция local_traverse() из модуля расширения _thread:

static int
local_traverse(PyObject *op, visitproc visit, void *arg)
{
    localobject *self = (localobject *) op;
    Py_VISIT(self->args);
    Py_VISIT(self->kw);
    Py_VISIT(self->dict);
    return 0;
}

Обратите внимание, что Py_VISIT() вызывается только для тех членов, которые могут участвовать в циклических ссылках. Хотя также имеется член self->key, он может быть только NULL или строкой Python и поэтому не может участвовать в циклической ссылке.

С другой стороны, даже если вы знаете, что член не может участвовать в цикле, для отладки можно всё же посетить его, чтобы функция gc модуля get_referents() включала его в результат.

Типы в куче (Py_TPFLAGS_HEAPTYPE) должны посещать свой тип с помощью:

Py_VISIT(Py_TYPE(self));

Это необходимо только начиная с Python 3.9. Для поддержки Python 3.8 и более ранних версий эту строку следует выполнять условно:

#if PY_VERSION_HEX >= 0x03090000
    Py_VISIT(Py_TYPE(self));
#endif

Если в поле tp_flags установлен бит Py_TPFLAGS_MANAGED_DICT, функция обхода должна вызывать PyObject_VisitManagedDict() следующим образом:

PyObject_VisitManagedDict((PyObject*)self, visit, arg);

Предупреждение

При реализации tp_traverse необходимо посещать только те члены, которыми экземпляр владеет (то есть имеет на них сильные ссылки). Например, если объект поддерживает слабые ссылки с помощью слота tp_weaklist, указатель, поддерживающий связанный список (то, на что указывает tp_weaklist), не следует посещать, поскольку экземпляр напрямую не владеет слабыми ссылками на себя (список слабых ссылок нужен для работы механизма слабых ссылок, но экземпляр не имеет сильных ссылок на содержащиеся в нём элементы, так как их можно удалить, даже если экземпляр всё ещё существует).

Предупреждение

Функция обхода не должна иметь побочных эффектов. Она не должна изменять счётчики ссылок каких-либо объектов Python, а также создавать или уничтожать объекты Python.

Обратите внимание, что Py_VISIT() требует, чтобы параметры visit и arg в local_traverse() имели именно эти имена; не называйте их как-нибудь иначе.

Экземпляры типов, размещённых в куче хранят ссылку на свой тип. Поэтому их функция обхода должна либо посещать Py_TYPE(self), либо передавать эту обязанность, вызывая tp_traverse другого типа, размещённого в куче (например, суперкласса, размещённого в куче). В противном случае объект типа может не быть собран сборщиком мусора.

Примечание

Функция tp_traverse может вызываться из любого потока.

Изменено в версии 3.9: Ожидается, что типы, размещённые в куче, будут посещать Py_TYPE(self) в tp_traverse. В более ранних версиях Python из-за ошибки 40217 это может приводить к аварийному завершению работы в подклассах.

Наследование:

Группа: Py_TPFLAGS_HAVE_GC, tp_traverse, tp_clear

Это поле наследуется подклассами вместе с tp_clear и битом флага Py_TPFLAGS_HAVE_GC: бит флага, tp_traverse и tp_clear наследуются от базового типа, если в подклассе они все равны нулю.

inquiry PyTypeObject.tp_clear

Соответствующий идентификатор слота Py_tp_clear входит в стабильный ABI.

Необязательный указатель на функцию очистки. Сигнатура:

int tp_clear(PyObject *);

Назначение этой функции — разорвать циклы ссылок, которые приводят к образованию циклически изолированной группы объектов, чтобы объекты можно было безопасно уничтожить. Очищенный объект является частично уничтоженным; он не обязан соблюдать инварианты, действующие при обычном использовании.

tp_clear не требуется удалять ссылки на объекты, которые не могут участвовать в циклах ссылок, например строки Python или целые числа Python. Однако может быть удобно очистить все ссылки и написать функцию типа tp_dealloc, вызывающую tp_clear, чтобы избежать дублирования кода. (Имейте в виду, что tp_clear уже могла быть вызвана. Предпочтительнее вызывать идемпотентные функции, например Py_CLEAR().)

Любую нетривиальную очистку следует выполнять в tp_finalize, а не в tp_clear.

Примечание

Если tp_clear не удастся разорвать цикл ссылок, объекты в циклически изолированной группе объектов могут навсегда остаться недоступными для сборщика мусора («утечь»). См. gc.garbage.

Примечание

Объекты, на которые ссылается данный объект (непосредственно или косвенно), могли быть уже очищены; их согласованное состояние не гарантируется.

Примечание

Функция tp_clear может быть вызвана из любого потока.

Примечание

Не гарантируется, что объект будет автоматически очищен до вызова его деструктора (tp_dealloc).

Эта функция отличается от деструктора (tp_dealloc) следующим:

  • Очистка объекта предназначена для удаления ссылок на другие объекты, которые могут участвовать в цикле ссылок. Назначение деструктора шире: он должен освободить все принадлежащие объекту ресурсы, включая ссылки на объекты, которые не могут участвовать в цикле ссылок (например, целые числа), а также память самого объекта (вызвав tp_free).
  • При вызове tp_clear другие объекты всё ещё могут хранить ссылки на очищаемый объект. Поэтому tp_clear не должна освобождать память самого объекта (tp_free). Деструктор же вызывается только при отсутствии (сильных) ссылок и поэтому должен безопасно уничтожить сам объект, освободив его память.
  • tp_clear может никогда не вызываться автоматически. Деструктор объекта, напротив, будет автоматически вызван через некоторое время после того, как объект станет недостижимым (то есть на объект не будет ссылок либо он будет членом циклически изолированной группы объектов).

Не гарантируется, когда, будет ли и как часто Python автоматически очищать объект, за исключением следующего:

  • Python не будет автоматически очищать объект, если он достижим, то есть на него есть ссылка и он не является членом циклически изолированной группы объектов.
  • Python не будет автоматически очищать объект, если он ещё не был автоматически финализирован (см. tp_finalize). (Если финализатор воскресил объект, перед очисткой объект может быть финализирован повторно, а может и не быть.)
  • Если объект является членом циклически изолированной группы объектов, Python не будет автоматически очищать его, если какой-либо член этой группы ещё не был автоматически финализирован (tp_finalize).
  • Python не будет уничтожать объект, пока не завершатся все автоматические вызовы его функции tp_clear. Это гарантирует, что разрыв цикла ссылок не сделает указатель self недействительным, пока ещё выполняется tp_clear.
  • Python не будет автоматически вызывать tp_clear одновременно несколько раз.

В настоящее время CPython автоматически очищает объекты только при необходимости разорвать циклы ссылок в циклически изолированной группе объектов, однако в будущих версиях объекты могут регулярно очищаться перед уничтожением.

В совокупности все функции tp_clear в системе должны разрывать все циклы ссылок. Это непростая задача; если вы не уверены, предоставьте функцию tp_clear. Например, тип tuple не реализует функцию tp_clear, поскольку можно доказать, что цикл ссылок не может состоять только из кортежей. Поэтому функции tp_clear других типов отвечают за разрыв любых циклов, содержащих кортеж. Это не сразу очевидно, и обычно нет веских причин отказываться от реализации tp_clear.

Реализации tp_clear должны сбрасывать ссылки экземпляра на те его члены, которые могут быть объектами Python, и устанавливать указатели на эти члены в NULL, как показано в следующем примере:

static int
local_clear(PyObject *op)
{
    localobject *self = (localobject *) op;
    Py_CLEAR(self->key);
    Py_CLEAR(self->args);
    Py_CLEAR(self->kw);
    Py_CLEAR(self->dict);
    return 0;
}

Следует использовать макрос Py_CLEAR(), поскольку очистка ссылок требует осторожности: ссылку на содержащийся объект нельзя освобождать (посредством Py_DECREF()), пока указатель на содержащийся объект не будет установлен в NULL. Это связано с тем, что освобождение ссылки может привести к тому, что содержащийся объект станет мусором и запустит цепочку действий по его удалению, в которую может входить выполнение произвольного кода Python (из-за финализаторов или обратных вызовов weakref, связанных с содержащимся объектом). Если такой код может снова обратиться к self, важно, чтобы указатель на содержащийся объект к этому моменту имел значение NULL, чтобы self знал, что содержащийся объект больше нельзя использовать. Макрос Py_CLEAR() выполняет операции в безопасном порядке.

Если в поле tp_flags установлен бит Py_TPFLAGS_MANAGED_DICT, функция очистки должна вызвать PyObject_ClearManagedDict() следующим образом:

PyObject_ClearManagedDict((PyObject*)self);

Дополнительные сведения о схеме сборки мусора Python приведены в разделе Поддержка обнаружения циклического мусора.

Наследование:

Группа: Py_TPFLAGS_HAVE_GC, tp_traverse, tp_clear

Это поле наследуется подтипами вместе с tp_traverse и битом флага Py_TPFLAGS_HAVE_GC: бит флага, tp_traverse и tp_clear наследуются от базового типа, если все они равны нулю в подтипе.

См. также

Подробнее о связи этого слота с другими слотами см. в разделе Жизненный цикл объекта.

richcmpfunc PyTypeObject.tp_richcompare

Соответствующий идентификатор слота Py_tp_richcompare входит в стабильный ABI.

Необязательный указатель на функцию расширенного сравнения со следующей сигнатурой:

PyObject *tp_richcompare(PyObject *self, PyObject *other, int op);

Гарантируется, что первый параметр является экземпляром типа, определённого в PyTypeObject.

Функция должна возвращать результат сравнения (обычно Py_True или Py_False). Если сравнение не определено, она должна вернуть Py_NotImplemented; если произошла другая ошибка, она должна вернуть NULL и установить состояние исключения.

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

Константа

Сравнение

Py_LT

<

Py_LE

<=

Py_EQ

==

Py_NE

!=

Py_GT

>

Py_GE

>=

Для упрощения написания функций расширенного сравнения определён следующий макрос:

Py_RETURN_RICHCOMPARE(VAL_A, VAL_B, op)

Возвращает из функции Py_True или Py_False в зависимости от результата сравнения. VAL_A и VAL_B должны сравниваться операторами сравнения C (например, это могут быть целые числа или числа с плавающей точкой C). Третий аргумент задаёт запрошенную операцию, как и для PyObject_RichCompare().

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

В случае ошибки устанавливает исключение и возвращает из функции NULL.

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

Наследование:

Группа: tp_hash, tp_richcompare

Это поле наследуется подтипами вместе с tp_hash: подтип наследует tp_richcompare и tp_hash, если его tp_richcompare и tp_hash равны NULL.

По умолчанию:

PyBaseObject_Type предоставляет реализацию tp_richcompare, которая может быть унаследована. Однако, если определён только tp_hash, унаследованная функция также не используется, и экземпляры этого типа не смогут участвовать ни в каких сравнениях.

Py_ssize_t PyTypeObject.tp_weaklistoffset

Хотя это поле по-прежнему поддерживается, вместо него по возможности следует использовать Py_TPFLAGS_MANAGED_WEAKREF.

Если экземпляры этого типа поддерживают слабые ссылки, значение этого поля больше нуля и содержит смещение начала списка слабых ссылок в структуре экземпляра (без учёта заголовка GC, если он есть); это смещение используется функцией PyObject_ClearWeakRefs() и функциями PyWeakref_*. Структура экземпляра должна включать поле типа PyObject*, инициализированное значением NULL.

Не путайте это поле с tp_weaklist; там хранится начало списка слабых ссылок на сам объект типа.

Устанавливать одновременно бит Py_TPFLAGS_MANAGED_WEAKREF и tp_weaklistoffset нельзя.

Наследование:

Это поле наследуется подтипами, но см. правила ниже. Подтип может переопределить это смещение; это означает, что подтип использует другое начало списка слабых ссылок, чем базовый тип. Поскольку начало списка всегда определяется через tp_weaklistoffset, проблем возникнуть не должно.

Значение по умолчанию:

Если в поле tp_flags установлен бит Py_TPFLAGS_MANAGED_WEAKREF, то tp_weaklistoffset будет присвоено отрицательное значение, указывающее на то, что это поле небезопасно использовать.

getiterfunc PyTypeObject.tp_iter

Соответствующий идентификатор слота Py_tp_iter входит в Стабильный ABI.

Необязательный указатель на функцию, возвращающую итератор для объекта. Обычно его наличие означает, что экземпляры этого типа являются итерируемыми (хотя последовательности могут быть итерируемыми и без этой функции).

Эта функция имеет ту же сигнатуру, что и PyObject_GetIter():

PyObject *tp_iter(PyObject *self);

Наследование:

Это поле наследуется подтипами.

iternextfunc PyTypeObject.tp_iternext

Соответствующий идентификатор слота Py_tp_iternext входит в Стабильный ABI.

Необязательный указатель на функцию, возвращающую следующий элемент итератора. Сигнатура:

PyObject *tp_iternext(PyObject *self);

Когда итератор исчерпан, функция должна вернуть NULL; исключение StopIteration может быть установлено, а может и нет. При возникновении другой ошибки функция также должна вернуть NULL. Наличие этой функции означает, что экземпляры этого типа являются итераторами.

Типы итераторов также должны определять функцию tp_iter, которая должна возвращать сам экземпляр итератора (а не новый экземпляр итератора).

Эта функция имеет ту же сигнатуру, что и PyIter_Next().

Наследование:

Это поле наследуется подтипами.

struct PyMethodDef *PyTypeObject.tp_methods

Соответствующий идентификатор слота Py_tp_methods входит в Стабильный ABI.

Необязательный указатель на статический массив структур PyMethodDef, завершённый значением NULL, в котором объявлены обычные методы этого типа.

Для каждой записи массива в словарь типа (см. tp_dict ниже) добавляется запись, содержащая дескриптор метода.

Наследование:

Это поле не наследуется подтипами (методы наследуются с помощью другого механизма).

struct PyMemberDef *PyTypeObject.tp_members

Соответствующий идентификатор слота Py_tp_members входит в Стабильный ABI.

Необязательный указатель на статический массив структур PyMemberDef, завершённый значением NULL, в котором объявлены обычные элементы данных (поля или слоты) экземпляров этого типа.

Для каждой записи массива в словарь типа (см. tp_dict ниже) добавляется запись, содержащая дескриптор элемента.

Наследование:

Это поле не наследуется подтипами (элементы наследуются с помощью другого механизма).

struct PyGetSetDef *PyTypeObject.tp_getset

Соответствующий идентификатор слота Py_tp_getset входит в Стабильный ABI.

Необязательный указатель на статический массив структур PyGetSetDef, завершённый значением NULL, в котором объявлены вычисляемые атрибуты экземпляров этого типа.

Для каждой записи массива в словарь типа (см. tp_dict ниже) добавляется запись, содержащая дескриптор getset.

Наследование:

Это поле не наследуется подтипами (вычисляемые атрибуты наследуются с помощью другого механизма).

PyTypeObject *PyTypeObject.tp_base

Соответствующий идентификатор слота Py_tp_base входит в Стабильный ABI.

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

Примечание

Инициализация слотов подчиняется правилам инициализации глобальных переменных. C99 требует, чтобы инициализаторы были «константами-адресами». Дизайнаторы функций, такие как PyType_GenericNew(), с неявным преобразованием в указатель, являются допустимыми константами-адресами в C99.

Однако стандарт не требует, чтобы унарный оператор «&», применённый к нестатической переменной, такой как PyBaseObject_Type, давал константу-адрес. Компиляторы могут поддерживать это (gcc поддерживает), MSVC — нет. В этом конкретном случае оба компилятора строго соответствуют стандарту.

Поэтому tp_base следует задавать в функции инициализации модуля расширения.

Наследование:

Это поле не наследуется подтипами (что очевидно).

Значение по умолчанию:

По умолчанию это поле имеет значение &PyBaseObject_Type (программистам на Python оно известно как тип object).

PyObject *PyTypeObject.tp_dict

Словарь типа хранится здесь функцией PyType_Ready().

Обычно это поле следует инициализировать значением NULL до вызова PyType_Ready; его также можно инициализировать словарём с начальными атрибутами типа. После инициализации типа функцией PyType_Ready() в этот словарь можно добавлять дополнительные атрибуты типа, только если они не соответствуют перегруженным операциям (например, __add__()). После завершения инициализации типа это поле следует считать доступным только для чтения.

Некоторые типы могут не хранить свой словарь в этом слоте. Для получения словаря произвольного типа используйте PyType_GetDict().

Изменено в версии 3.12: Внутренняя деталь реализации: для статических встроенных типов это значение всегда равно NULL. Вместо этого словарь таких типов хранится в PyInterpreterState. Для получения словаря произвольного типа используйте PyType_GetDict().

Наследование:

Это поле не наследуется подтипами (хотя атрибуты, определённые в нём, наследуются с помощью другого механизма).

Значение по умолчанию:

Если значение этого поля равно NULL, функция PyType_Ready() присвоит ему новый словарь.

Предупреждение

Использовать PyDict_SetItem() для изменения tp_dict или каким-либо иным образом изменять его с помощью C API словарей небезопасно.

descrgetfunc PyTypeObject.tp_descr_get

Соответствующий идентификатор слота Py_tp_descr_get входит в Стабильный ABI.

Необязательный указатель на функцию получения значения дескриптора.

Сигнатура функции:

PyObject * tp_descr_get(PyObject *self, PyObject *obj, PyObject *type);

Наследование:

Это поле наследуется подтипами.

descrsetfunc PyTypeObject.tp_descr_set

Соответствующий идентификатор слота Py_tp_descr_set входит в Стабильный ABI.

Необязательный указатель на функцию установки и удаления значения дескриптора.

Сигнатура функции:

int tp_descr_set(PyObject *self, PyObject *obj, PyObject *value);

Аргумент value получает значение NULL, если значение нужно удалить.

Наследование:

Это поле наследуется подтипами.

Py_ssize_t PyTypeObject.tp_dictoffset

Хотя это поле по-прежнему поддерживается, по возможности вместо него следует использовать Py_TPFLAGS_MANAGED_DICT.

Если экземпляры этого типа имеют словарь с переменными экземпляра, это поле не равно нулю и содержит смещение словаря переменных экземпляра в экземплярах типа; это смещение используется функцией PyObject_GenericGetAttr().

Не путайте это поле с tp_dict; это словарь атрибутов самого объекта типа.

Значение задаёт смещение словаря относительно начала структуры экземпляра.

Поле tp_dictoffset следует считать доступным только для записи. Чтобы получить указатель на словарь, вызовите PyObject_GenericGetDict(). Вызов PyObject_GenericGetDict() может потребовать выделения памяти для словаря, поэтому при обращении к атрибуту объекта может быть эффективнее вызвать PyObject_GetAttr().

Устанавливать одновременно бит Py_TPFLAGS_MANAGED_DICT и поле tp_dictoffset нельзя.

Наследование:

Это поле наследуется подклассами. Подкласс не должен переопределять это смещение: это может быть небезопасно, если код C попытается обратиться к словарю по прежнему смещению. Для корректной поддержки наследования используйте Py_TPFLAGS_MANAGED_DICT.

Значение по умолчанию:

У этого слота нет значения по умолчанию. Для статических типов, если поле равно NULL, для экземпляров не создаётся __dict__.

Если в поле tp_flags установлен бит Py_TPFLAGS_MANAGED_DICT, то для tp_dictoffset устанавливается значение -1, указывающее, что использовать это поле небезопасно.

initproc PyTypeObject.tp_init

Соответствующий идентификатор слота Py_tp_init входит в стабильный ABI.

Необязательный указатель на функцию инициализации экземпляра.

Эта функция соответствует методу __init__() классов. Как и в случае с __init__(), экземпляр можно создать, не вызывая __init__(), а также повторно инициализировать, снова вызвав его метод __init__().

Сигнатура функции:

int tp_init(PyObject *self, PyObject *args, PyObject *kwds);

Аргумент self — это инициализируемый экземпляр; аргументы args и kwds представляют позиционные и именованные аргументы вызова __init__().

Функция tp_init, если она не равна NULL, вызывается при обычном создании экземпляра вызовом его типа после того, как функция типа tp_new вернула экземпляр этого типа. Если функция tp_new возвращает экземпляр другого типа, не являющегося подклассом исходного типа, функция tp_init не вызывается; если tp_new возвращает экземпляр подкласса исходного типа, вызывается функция tp_init этого подкласса.

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

Наследование:

Это поле наследуется подклассами.

Значение по умолчанию:

Для статических типов значение этого поля не задано по умолчанию.

allocfunc PyTypeObject.tp_alloc

Соответствующий идентификатор слота Py_tp_alloc входит в стабильный ABI.

Необязательный указатель на функцию выделения памяти для экземпляра.

Сигнатура функции:

PyObject *tp_alloc(PyTypeObject *self, Py_ssize_t nitems);

Наследование:

Статические подклассы наследуют этот слот; если он унаследован от object, его значением будет PyType_GenericAlloc().

Подклассы в куче не наследуют этот слот.

Значение по умолчанию:

Для подклассов в куче этому полю всегда присваивается значение PyType_GenericAlloc().

Статические подклассы наследуют этот слот (см. выше).

newfunc PyTypeObject.tp_new

Соответствующий идентификатор слота Py_tp_new входит в стабильный ABI.

Необязательный указатель на функцию создания экземпляра.

Сигнатура функции:

PyObject *tp_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds);

Аргумент subtype — это тип создаваемого объекта; аргументы args и kwds представляют позиционные и именованные аргументы вызова типа. Обратите внимание: subtype не обязательно должен совпадать с типом, чья функция tp_new вызывается; он может быть подклассом этого типа (но не несвязанным типом).

Функция tp_new должна вызвать subtype->tp_alloc(subtype, nitems), чтобы выделить память для объекта, а затем выполнить только ту дополнительную инициализацию, которая абсолютно необходима. Инициализацию, которую можно безопасно пропустить или повторить, следует выполнять в обработчике tp_init. Как правило, для неизменяемых типов вся инициализация должна выполняться в tp_new, а для изменяемых типов большую её часть следует отложить до tp_init.

Установите флаг Py_TPFLAGS_DISALLOW_INSTANTIATION, чтобы запретить создание экземпляров типа в Python.

Наследование:

Это поле наследуется подклассами, кроме статических типов, у которых tp_base равно NULL или &PyBaseObject_Type.

Значение по умолчанию:

Для статических типов значение этого поля не задано по умолчанию. Это означает, что если для слота задано значение NULL, тип нельзя вызвать для создания новых экземпляров; предположительно, экземпляры создаются другим способом, например с помощью фабричной функции.

freefunc PyTypeObject.tp_free

Соответствующий идентификатор слота Py_tp_free входит в стабильный ABI.

Необязательный указатель на функцию освобождения памяти экземпляра. Её сигнатура:

void tp_free(void *self);

Эта функция должна освободить память, выделенную функцией tp_alloc.

Наследование:

Статические подклассы наследуют этот слот; если он унаследован от object, его значением будет PyObject_Free(). Исключение: если тип поддерживает сборку мусора (то есть в поле tp_flags установлен флаг Py_TPFLAGS_HAVE_GC) и унаследовал бы PyObject_Free(), этот слот не наследуется, а вместо этого по умолчанию получает значение PyObject_GC_Del().

Подклассы в куче не наследуют этот слот.

Значение по умолчанию:

Для подклассов в куче по умолчанию используется деаллокатор, соответствующий PyType_GenericAlloc() и значению флага Py_TPFLAGS_HAVE_GC.

Статические подклассы наследуют этот слот (см. выше).

inquiry PyTypeObject.tp_is_gc

Соответствующий идентификатор слота Py_tp_is_gc входит в стабильный ABI.

Необязательный указатель на функцию, вызываемую сборщиком мусора.

Сборщику мусора нужно знать, подлежит ли конкретный объект сборке. Обычно для этого достаточно проверить поле tp_flags типа объекта и бит флага Py_TPFLAGS_HAVE_GC. Однако у некоторых типов есть как статически, так и динамически выделенные экземпляры, причём статически выделенные экземпляры не подлежат сборке мусора. Такие типы должны определять эту функцию; она должна возвращать 1 для экземпляра, подлежащего сборке мусора, и 0 для экземпляра, который ей не подлежит. Сигнатура:

int tp_is_gc(PyObject *self);

(Единственный пример — сами типы. Метатип PyType_Type определяет эту функцию, чтобы различать статически и динамически выделенные типы.)

Наследование:

Это поле наследуется подклассами.

Значение по умолчанию:

У этого слота нет значения по умолчанию. Если поле равно NULL, в качестве функционального эквивалента используется Py_TPFLAGS_HAVE_GC.

PyObject *PyTypeObject.tp_bases

Соответствующий идентификатор слота Py_tp_bases входит в стабильный ABI.

Кортеж базовых типов.

Для этого поля следует установить значение NULL и считать его доступным только для чтения. Python заполнит его при вызове initialized для типа.

Для динамически создаваемых классов слот Py_tp_bases slot можно использовать вместо аргумента bases функции PyType_FromSpecWithBases(). Предпочтительнее использовать аргумент.

Предупреждение

Множественное наследование плохо работает со статически определёнными типами. Если присвоить tp_bases кортеж, Python не вызовет ошибку, но некоторые слоты будут унаследованы только от первого базового типа.

Наследование:

Это поле не наследуется.

PyObject *PyTypeObject.tp_mro

Кортеж, содержащий полный набор базовых типов: он начинается с самого типа и заканчивается object, в порядке разрешения методов.

Это поле следует устанавливать в NULL и считать доступным только для чтения. Python заполнит его, когда тип будет готов с помощью initialized.

Наследование:

Это поле не наследуется; его значение вычисляется заново функцией PyType_Ready().

PyObject *PyTypeObject.tp_cache

Не используется. Только для внутреннего использования.

Наследование:

Это поле не наследуется.

void *PyTypeObject.tp_subclasses

Коллекция подклассов. Только для внутреннего использования. Может содержать недопустимый указатель.

Чтобы получить список подклассов, вызовите метод Python __subclasses__().

Изменено в версии 3.12: У некоторых типов это поле не содержит допустимый PyObject*. Тип был изменён на void*, чтобы это обозначить.

Наследование:

Это поле не наследуется.

PyObject *PyTypeObject.tp_weaklist

Голова списка слабых ссылок на этот объект типа. Не наследуется. Только для внутреннего использования.

Изменено в версии 3.12: Подробность реализации: у встроенных статических типов это поле всегда равно NULL, даже если добавлены слабые ссылки. Вместо этого слабые ссылки для каждого из них хранятся в PyInterpreterState. Используйте публичный C API или внутренний макрос _PyObject_GET_WEAKREFS_LISTPTR(), чтобы не учитывать это различие.

Наследование:

Это поле не наследуется.

destructor PyTypeObject.tp_del

Соответствующий идентификатор слота Py_tp_del входит в стабильный ABI.

Это поле устарело. Вместо него используйте tp_finalize.

unsigned int PyTypeObject.tp_version_tag

Используется для индексации кэша методов. Только для внутреннего использования.

Наследование:

Это поле не наследуется.

destructor PyTypeObject.tp_finalize

Соответствующий идентификатор слота Py_tp_finalize входит в стабильный ABI начиная с версии 3.5.

Необязательный указатель на функцию финализации экземпляра. Это реализация на C специального метода __del__(). Её сигнатура:

void tp_finalize(PyObject *self);

Основная цель финализации — выполнить все нетривиальные операции очистки, которые необходимо провести до уничтожения объекта, пока сам объект и все объекты, на которые он прямо или косвенно ссылается, находятся в согласованном состоянии. Финализатору разрешено выполнять произвольный код Python.

До того как Python автоматически финализирует объект, некоторые прямые или косвенные объекты, на которые он ссылается, могли уже быть автоматически финализированы. Однако ни один из этих объектов ещё не был автоматически очищен (см. tp_clear).

Другие нефинализированные объекты всё ещё могут использовать финализированный объект, поэтому финализатор должен оставить объект в разумном состоянии (например, инварианты должны по-прежнему выполняться).

Примечание

После автоматической финализации объекта Python может начать автоматически очищать (см. tp_clear) этот объект и объекты, на которые он ссылается (прямо или косвенно). Очищенные объекты не обязательно находятся в согласованном состоянии; финализированный объект должен корректно работать с очищенными объектами, на которые он ссылается.

Примечание

Не гарантируется, что объект будет автоматически финализирован до вызова его деструктора (tp_dealloc). Рекомендуется вызывать PyObject_CallFinalizerFromDealloc() в начале tp_dealloc, чтобы гарантировать финализацию объекта до его уничтожения.

Примечание

Функция tp_finalize может быть вызвана из любого потока, однако при этом будет удерживаться GIL.

Примечание

Функция tp_finalize может быть вызвана во время завершения работы после удаления некоторых глобальных переменных. Подробности см. в документации метода __del__().

При финализации объекта Python действует по следующему алгоритму:

  1. Python может пометить объект как финализированный. В настоящее время Python всегда помечает объекты, тип которых поддерживает сборку мусора (то есть в tp_flags установлен флаг Py_TPFLAGS_HAVE_GC), и никогда не помечает объекты других типов; в будущей версии это может измениться.
  2. Если объект не помечен как финализированный, а его функция финализации tp_finalize не равна NULL, вызывается эта функция.
  3. Если функция финализации была вызвана и объект стал доступен из программы (то есть на объект имеется ссылка, и он не является членом циклического изолята), считается, что финализатор воскресил объект. Не определено, может ли финализатор также воскресить объект, добавив на него новую ссылку, которая не сделает его доступным из программы, то есть объект по-прежнему останется членом циклического изолята.
  4. Если финализатор воскресил объект, его предстоящее уничтожение отменяется, а отметка финализированного объекта может быть снята, если она была установлена. В настоящее время Python никогда не снимает эту отметку; в будущей версии это может измениться.

Автоматическая финализация — это любая финализация, выполняемая Python, кроме вызовов PyObject_CallFinalizer() или PyObject_CallFinalizerFromDealloc(). Не гарантируется, когда, будет ли и как часто объект финализирован автоматически, за исключением следующих случаев:

  • Python не будет автоматически финализировать объект, если он доступен из программы, то есть на него имеется ссылка, и он не является членом циклического изолята.
  • Python не будет автоматически финализировать объект, если его финализация не пометит объект как финализированный. В настоящее время это относится к объектам, тип которых не поддерживает сборку мусора, то есть флаг Py_TPFLAGS_HAVE_GC не установлен. Такие объекты всё же можно финализировать вручную, вызвав PyObject_CallFinalizer() или PyObject_CallFinalizerFromDealloc().
  • Python не будет автоматически финализировать одновременно два объекта, являющихся членами одного циклического изолята.
  • Python не будет автоматически финализировать объект после его автоматической очистки (см. tp_clear).
  • Если объект является членом циклического изолята, Python не будет автоматически финализировать его после автоматической очистки (см. tp_clear) любого другого члена.
  • Python автоматически финализирует каждый объект, являющийся членом циклического изолята, прежде чем автоматически очистит (см. tp_clear) любой из них.
  • Если Python собирается автоматически очистить объект (tp_clear), он сначала автоматически финализирует этот объект.

В настоящее время Python автоматически финализирует только объекты, являющиеся членами циклического изолята, однако в будущих версиях объекты могут финализироваться регулярно, до их уничтожения.

Чтобы вручную финализировать объект, не вызывайте эту функцию напрямую; вместо неё вызовите PyObject_CallFinalizer() или PyObject_CallFinalizerFromDealloc().

tp_finalize должна оставлять текущее состояние исключения неизменным. Рекомендуемый способ написания нетривиального финализатора — сохранить исключение в начале вызовом PyErr_GetRaisedException(), а в конце восстановить его вызовом PyErr_SetRaisedException(). Если в ходе финализации возникает исключение, зарегистрируйте его и очистите состояние исключения с помощью PyErr_WriteUnraisable() или PyErr_FormatUnraisable(). Например:

static void
foo_finalize(PyObject *self)
{
    // Save the current exception, if any.
    PyObject *exc = PyErr_GetRaisedException();

    // ...

    if (do_something_that_might_raise() != success_indicator) {
        PyErr_WriteUnraisable(self);
        goto done;
    }

done:
    // Restore the saved exception.  This silently discards any exception
    // raised above, so be sure to call PyErr_WriteUnraisable first if
    // necessary.
    PyErr_SetRaisedException(exc);
}

Наследование:

Это поле наследуется подклассами.

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

Изменено в версии 3.8: До версии 3.8 для использования этого поля требовалось устанавливать бит флага Py_TPFLAGS_HAVE_FINALIZE. Теперь это не требуется.

См. также

  • PEP 442: «Безопасная финализация объектов»
  • Жизненный цикл объекта: подробности о связи этого слота с другими слотами.
  • PyObject_CallFinalizer()
  • PyObject_CallFinalizerFromDealloc()
vectorcallfunc PyTypeObject.tp_vectorcall

Соответствующий идентификатор слота Py_tp_vectorcall входит в стабильный ABI начиная с версии 3.14.

Функция vectorcall, используемая для вызовов этого объекта типа (а не его экземпляров). Иными словами, tp_vectorcall можно использовать для оптимизации type.__call__, которая обычно возвращает новый экземпляр типа.

Как и в случае с любой функцией vectorcall, если tp_vectorcall равно NULL, вместо этого используется протокол tp_call (Py_TYPE(type)->tp_call).

Примечание

Протокол vectorcall требует, чтобы функция vectorcall имела такое же поведение, как соответствующий tp_call. Это означает, что type->tp_vectorcall должен соответствовать поведению Py_TYPE(type)->tp_call.

В частности, если тип использует метакласс по умолчанию, type->tp_vectorcall должен вести себя так же, как PyType_Type->tp_call, который:

  • вызывает type->tp_new,
  • если результат является подклассом типа, вызывает type->tp_init для результата tp_new и
  • возвращает результат tp_new.

Обычно tp_vectorcall переопределяют, чтобы оптимизировать этот процесс для конкретных tp_new и tp_init. При этом для типов, которые могут иметь пользовательские подклассы, учитывайте, что оба метода можно переопределить (с помощью __new__() и __init__() соответственно).

Наследование:

Это поле никогда не наследуется.

Добавлено в версии 3.9: (поле существует с версии 3.8, но используется только начиная с версии 3.9)

unsigned char PyTypeObject.tp_watched

Внутреннее поле. Не используйте.

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

Статические типы

Традиционно типы, определённые в коде на C, являются статическими: это означает, что статическая структура PyTypeObject определяется непосредственно в коде и инициализируется с помощью PyType_Ready().

В результате такие типы имеют ограничения по сравнению с типами, определёнными в Python:

  • Статические типы могут иметь только один базовый тип, то есть не поддерживают множественное наследование.
  • Объекты статических типов (но не обязательно их экземпляры) неизменяемы. Из Python нельзя добавлять или изменять атрибуты объекта типа.
  • Объекты статических типов совместно используются субинтерпретаторами, поэтому они не должны содержать состояние, специфичное для субинтерпретатора.

Кроме того, поскольку PyTypeObject входит в ограниченный API только как непрозрачная структура, любые модули расширения, использующие статические типы, необходимо компилировать для конкретной минорной версии Python.

Динамические типы

Альтернативой статическим типам являются типы, выделяемые в куче, или, короче, динамические типы, которые близки по устройству к классам, создаваемым оператором class в Python. У динамических типов установлен флаг Py_TPFLAGS_HEAPTYPE.

Для этого заполняют структуру PyType_Spec и вызывают PyType_FromSpec(), PyType_FromSpecWithBases(), PyType_FromModuleAndSpec() или PyType_FromMetaclass().

Структуры числовых объектов

type PyNumberMethods

Эта структура содержит указатели на функции, которые объект использует для реализации числового протокола. Каждая функция используется одноимённой функцией, описанной в разделе Числовой протокол.

Определение структуры:

typedef struct {
     binaryfunc nb_add;
     binaryfunc nb_subtract;
     binaryfunc nb_multiply;
     binaryfunc nb_remainder;
     binaryfunc nb_divmod;
     ternaryfunc nb_power;
     unaryfunc nb_negative;
     unaryfunc nb_positive;
     unaryfunc nb_absolute;
     inquiry nb_bool;
     unaryfunc nb_invert;
     binaryfunc nb_lshift;
     binaryfunc nb_rshift;
     binaryfunc nb_and;
     binaryfunc nb_xor;
     binaryfunc nb_or;
     unaryfunc nb_int;
     void *nb_reserved;
     unaryfunc nb_float;

     binaryfunc nb_inplace_add;
     binaryfunc nb_inplace_subtract;
     binaryfunc nb_inplace_multiply;
     binaryfunc nb_inplace_remainder;
     ternaryfunc nb_inplace_power;
     binaryfunc nb_inplace_lshift;
     binaryfunc nb_inplace_rshift;
     binaryfunc nb_inplace_and;
     binaryfunc nb_inplace_xor;
     binaryfunc nb_inplace_or;

     binaryfunc nb_floor_divide;
     binaryfunc nb_true_divide;
     binaryfunc nb_inplace_floor_divide;
     binaryfunc nb_inplace_true_divide;

     unaryfunc nb_index;

     binaryfunc nb_matrix_multiply;
     binaryfunc nb_inplace_matrix_multiply;
} PyNumberMethods;

Примечание

Бинарные и тернарные функции должны проверять типы всех своих операндов и выполнять необходимые преобразования (по крайней мере один из операндов является экземпляром определённого типа). Если операция не определена для заданных операндов, бинарные и тернарные функции должны возвращать Py_NotImplemented; если произошла другая ошибка, они должны возвращать NULL и устанавливать исключение.

Примечание

Поле nb_reserved всегда должно иметь значение NULL. Ранее оно называлось nb_long; это имя было изменено в Python 3.0.1.

binaryfunc PyNumberMethods.nb_add

Соответствующий идентификатор слота Py_nb_add входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_subtract

Соответствующий идентификатор слота Py_nb_subtract входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_multiply

Соответствующий идентификатор слота Py_nb_multiply входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_remainder

Соответствующий идентификатор слота Py_nb_remainder входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_divmod

Соответствующий идентификатор слота Py_nb_divmod входит в стабильный ABI.

ternaryfunc PyNumberMethods.nb_power

Соответствующий идентификатор слота Py_nb_power входит в стабильный ABI.

unaryfunc PyNumberMethods.nb_negative

Соответствующий идентификатор слота Py_nb_negative входит в стабильный ABI.

unaryfunc PyNumberMethods.nb_positive

Соответствующий идентификатор слота Py_nb_positive входит в стабильный ABI.

unaryfunc PyNumberMethods.nb_absolute

Соответствующий идентификатор слота Py_nb_absolute входит в стабильный ABI.

inquiry PyNumberMethods.nb_bool

Соответствующий идентификатор слота Py_nb_bool входит в стабильный ABI.

unaryfunc PyNumberMethods.nb_invert

Соответствующий идентификатор слота Py_nb_invert входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_lshift

Соответствующий идентификатор слота Py_nb_lshift входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_rshift

Соответствующий идентификатор слота Py_nb_rshift входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_and

Соответствующий идентификатор слота Py_nb_and входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_xor

Соответствующий идентификатор слота Py_nb_xor входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_or

Соответствующий идентификатор слота Py_nb_or входит в стабильный ABI.

unaryfunc PyNumberMethods.nb_int

Соответствующий идентификатор слота Py_nb_int входит в стабильный ABI.

void *PyNumberMethods.nb_reserved
unaryfunc PyNumberMethods.nb_float

Соответствующий идентификатор слота Py_nb_float входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_inplace_add

Соответствующий идентификатор слота Py_nb_inplace_add входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_inplace_subtract

Соответствующий идентификатор слота Py_nb_inplace_subtract входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_inplace_multiply

Соответствующий идентификатор слота Py_nb_inplace_multiply входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_inplace_remainder

Соответствующий идентификатор слота Py_nb_inplace_remainder входит в стабильный ABI.

ternaryfunc PyNumberMethods.nb_inplace_power

Соответствующий идентификатор слота Py_nb_inplace_power входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_inplace_lshift

Соответствующий идентификатор слота Py_nb_inplace_lshift входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_inplace_rshift

Соответствующий идентификатор слота Py_nb_inplace_rshift входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_inplace_and

Соответствующий идентификатор слота Py_nb_inplace_and входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_inplace_xor

Соответствующий идентификатор слота Py_nb_inplace_xor входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_inplace_or

Соответствующий идентификатор слота Py_nb_inplace_or входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_floor_divide

Соответствующий идентификатор слота Py_nb_floor_divide входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_true_divide

Соответствующий идентификатор слота Py_nb_true_divide входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_inplace_floor_divide

Соответствующий идентификатор слота Py_nb_inplace_floor_divide входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_inplace_true_divide

Соответствующий идентификатор слота Py_nb_inplace_true_divide входит в стабильный ABI.

unaryfunc PyNumberMethods.nb_index

Соответствующий идентификатор слота Py_nb_index входит в стабильный ABI.

binaryfunc PyNumberMethods.nb_matrix_multiply

Соответствующий идентификатор слота Py_nb_matrix_multiply входит в стабильный ABI начиная с версии 3.5.

binaryfunc PyNumberMethods.nb_inplace_matrix_multiply

Соответствующий идентификатор слота Py_nb_inplace_matrix_multiply входит в стабильный ABI начиная с версии 3.5.

Структуры объектов отображения

type PyMappingMethods

Эта структура содержит указатели на функции, с помощью которых объект реализует протокол отображения. Она имеет три поля:

lenfunc PyMappingMethods.mp_length

Соответствующий идентификатор слота Py_mp_length входит в стабильный ABI.

Эта функция используется функциями PyMapping_Size() и PyObject_Size() и имеет ту же сигнатуру. Для объектов с неопределённой длиной этому слоту можно присвоить NULL.

binaryfunc PyMappingMethods.mp_subscript

Соответствующий идентификатор слота Py_mp_subscript входит в стабильный ABI.

Эта функция используется функциями PyObject_GetItem() и PySequence_GetSlice() и имеет ту же сигнатуру, что и PyObject_GetItem(). Этот слот должен быть заполнен, чтобы функция PyMapping_Check() возвращала 1; в противном случае ему можно присвоить NULL.

objobjargproc PyMappingMethods.mp_ass_subscript

Соответствующий идентификатор слота Py_mp_ass_subscript входит в стабильный ABI.

Эта функция используется функциями PyObject_SetItem(), PyObject_DelItem(), PySequence_SetSlice() и PySequence_DelSlice(). Она имеет ту же сигнатуру, что и PyObject_SetItem(), но v также можно установить в NULL, чтобы удалить элемент. Если этому слоту присвоено NULL, объект не поддерживает присваивание и удаление элементов.

Структуры объектов последовательностей

type PySequenceMethods

Эта структура содержит указатели на функции, с помощью которых объект реализует протокол последовательности.

lenfunc PySequenceMethods.sq_length

Соответствующий идентификатор слота Py_sq_length входит в стабильный ABI.

Эта функция используется функциями PySequence_Size() и PyObject_Size() и имеет ту же сигнатуру. Она также используется для обработки отрицательных индексов слотами sq_item и sq_ass_item.

binaryfunc PySequenceMethods.sq_concat

Соответствующий идентификатор слота Py_sq_concat входит в стабильный ABI.

Эта функция используется функцией PySequence_Concat() и имеет ту же сигнатуру. Она также используется оператором + после попытки выполнить числовое сложение с помощью слота nb_add.

ssizeargfunc PySequenceMethods.sq_repeat

Соответствующий идентификатор слота Py_sq_repeat входит в стабильный ABI.

Эта функция используется функцией PySequence_Repeat() и имеет ту же сигнатуру. Она также используется оператором * после попытки выполнить числовое умножение с помощью слота nb_multiply.

ssizeargfunc PySequenceMethods.sq_item

Соответствующий идентификатор слота Py_sq_item входит в стабильный ABI.

Эта функция используется функцией PySequence_GetItem() и имеет ту же сигнатуру. Она также используется функцией PyObject_GetItem() после попытки выполнить индексирование с помощью слота mp_subscript. Этот слот должен быть заполнен, чтобы функция PySequence_Check() возвращала 1; в противном случае ему можно присвоить NULL.

Отрицательные индексы обрабатываются следующим образом: если слот sq_length заполнен, он вызывается, а длина последовательности используется для вычисления положительного индекса, который передаётся в sq_item. Если sq_length имеет значение NULL, индекс передаётся функции без изменений.

ssizeobjargproc PySequenceMethods.sq_ass_item

Соответствующий идентификатор слота Py_sq_ass_item входит в стабильный ABI.

Эта функция используется функцией PySequence_SetItem() и имеет ту же сигнатуру. Она также используется функциями PyObject_SetItem() и PyObject_DelItem() после попытки выполнить присваивание и удаление элемента с помощью слота mp_ass_subscript. Если объект не поддерживает присваивание и удаление элементов, этому слоту можно присвоить NULL.

objobjproc PySequenceMethods.sq_contains

Соответствующий идентификатор слота Py_sq_contains входит в стабильный ABI.

Эта функция может использоваться функцией PySequence_Contains() и имеет ту же сигнатуру. Этому слоту можно присвоить NULL; в этом случае PySequence_Contains() просто перебирает последовательность, пока не найдёт совпадение.

binaryfunc PySequenceMethods.sq_inplace_concat

Соответствующий идентификатор слота Py_sq_inplace_concat входит в стабильный ABI.

Эта функция используется функцией PySequence_InPlaceConcat() и имеет ту же сигнатуру. Она должна изменять свой первый операнд и возвращать его. Этому слоту можно присвоить NULL; в этом случае PySequence_InPlaceConcat() использует в качестве запасного варианта PySequence_Concat(). Он также используется при расширенном присваивании += после попытки выполнить числовое сложение на месте с помощью слота nb_inplace_add.

ssizeargfunc PySequenceMethods.sq_inplace_repeat

Соответствующий идентификатор слота Py_sq_inplace_repeat входит в стабильный ABI.

Эта функция используется функцией PySequence_InPlaceRepeat() и имеет ту же сигнатуру. Она должна изменять свой первый операнд и возвращать его. Этому слоту можно присвоить NULL; в этом случае PySequence_InPlaceRepeat() использует в качестве запасного варианта PySequence_Repeat(). Он также используется при расширенном присваивании *= после попытки выполнить числовое умножение на месте с помощью слота nb_inplace_multiply.

Структуры объектов буфера

type PyBufferProcs

Эта структура содержит указатели на функции, необходимые для протокола буфера. Протокол определяет, как объект-экспортер может предоставлять свои внутренние данные объектам-потребителям.

getbufferproc PyBufferProcs.bf_getbuffer

Соответствующий идентификатор слота Py_bf_getbuffer входит в стабильный ABI начиная с версии 3.11.

Сигнатура этой функции:

int (PyObject *exporter, Py_buffer *view, int flags);

Обрабатывает запрос к экспортеру заполнить view в соответствии с flags. За исключением пункта (3), реализация этой функции ДОЛЖНА выполнить следующие действия:

  1. Проверить, можно ли выполнить запрос. Если нет, вызвать исключение BufferError, установить view->obj в NULL и вернуть -1.
  2. Заполнить запрошенные поля.
  3. Увеличить внутренний счетчик количества экспортов.
  4. Установить view->obj в exporter и увеличить view->obj.
  5. Вернуть 0.

Потокобезопасность:

В сборке без GIL реализации должны обеспечивать следующее:

  • Увеличение счетчика экспортов на шаге (3) выполняется атомарно.
  • Базовые данные буфера остаются действительными и находятся по неизменному адресу в памяти в течение всего времени существования всех экспортов.
  • Для объектов, поддерживающих изменение размера или перераспределение памяти (например, bytearray), перед такими операциями счетчик экспортов проверяется атомарно, а если существуют экспорты, вызывается исключение BufferError.
  • Функцию можно безопасно вызывать одновременно из нескольких потоков.

Сведения о гарантиях потокобезопасности memoryview на уровне Python см. в разделе Потокобезопасность объектов memoryview.

Если exporter входит в цепочку или дерево поставщиков буфера, можно использовать две основные схемы:

  • Повторный экспорт: каждый элемент дерева выступает в роли экспортирующего объекта и устанавливает view->obj в новое сильное ссылочное значение на себя.
  • Перенаправление: запрос буфера перенаправляется корневому объекту дерева. В этом случае view->obj будет новым сильным ссылочным значением на корневой объект.

Отдельные поля view описаны в разделе Структура буфера, а правила поведения экспортера при определенных запросах приведены в разделе Типы запросов буфера.

Вся память, на которую указывают поля структуры Py_buffer, принадлежит экспортеру и должна оставаться действительной, пока существуют потребители. Поля format, shape, strides, suboffsets и internal доступны потребителю только для чтения.

PyBuffer_FillInfo() позволяет легко предоставить простой буфер байтов, корректно обрабатывая при этом все типы запросов.

PyObject_GetBuffer() — интерфейс потребителя, оборачивающий эту функцию.

releasebufferproc PyBufferProcs.bf_releasebuffer

Соответствующий идентификатор слота Py_bf_releasebuffer входит в стабильный ABI начиная с версии 3.11.

Сигнатура этой функции:

void (PyObject *exporter, Py_buffer *view);

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

  1. Уменьшить внутренний счетчик количества экспортов.
  2. Если значение счетчика равно 0, освободить всю память, связанную с view.

Потокобезопасность:

В сборке без GIL:

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

Экспортер ДОЛЖЕН использовать поле internal для отслеживания ресурсов, связанных с буфером. Это поле гарантированно остается неизменным, хотя потребитель МОЖЕТ передать копию исходного буфера в качестве аргумента view.

Эта функция НЕ ДОЛЖНА уменьшать view->obj, поскольку это автоматически выполняется в PyBuffer_Release() (эта схема полезна для разрыва циклов ссылок).

PyBuffer_Release() — интерфейс потребителя, оборачивающий эту функцию.

Структуры асинхронных объектов

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

type PyAsyncMethods

Эта структура содержит указатели на функции, необходимые для реализации объектов ожидаемого объекта и асинхронного итератора.

Определение структуры:

typedef struct {
    unaryfunc am_await;
    unaryfunc am_aiter;
    unaryfunc am_anext;
    sendfunc am_send;
} PyAsyncMethods;
unaryfunc PyAsyncMethods.am_await

Соответствующий идентификатор слота Py_am_await входит в стабильный ABI начиная с версии 3.5.

Сигнатура этой функции:

PyObject *am_await(PyObject *self);

Возвращаемый объект должен быть итератором, то есть для него PyIter_Check() должен возвращать 1.

Для объекта, который не является ожидаемым объектом, этому слоту можно присвоить значение NULL.

unaryfunc PyAsyncMethods.am_aiter

Соответствующий идентификатор слота Py_am_aiter входит в стабильный ABI начиная с версии 3.5.

Сигнатура этой функции:

PyObject *am_aiter(PyObject *self);

Должна возвращать объект асинхронного итератора. Подробности см. в __anext__().

Для объекта, который не реализует протокол асинхронной итерации, этому слоту можно присвоить значение NULL.

unaryfunc PyAsyncMethods.am_anext

Соответствующий идентификатор слота Py_am_anext входит в стабильный ABI начиная с версии 3.5.

Сигнатура этой функции:

PyObject *am_anext(PyObject *self);

Должна возвращать объект ожидаемого объекта. Подробности см. в __anext__(). Этому слоту можно присвоить значение NULL.

sendfunc PyAsyncMethods.am_send

Соответствующий идентификатор слота Py_am_send входит в стабильный ABI начиная с версии 3.10.

Сигнатура этой функции:

PySendResult am_send(PyObject *self, PyObject *arg, PyObject **result);

Подробности см. в PyIter_Send(). Этому слоту можно присвоить значение NULL.

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

Определения типов слотов

typedef PyObject *(*allocfunc)(PyTypeObject *cls, Py_ssize_t nitems)
Часть стабильного ABI.

Назначение этой функции — отделить выделение памяти от инициализации памяти. Она должна возвращать указатель на блок памяти достаточной длины для экземпляра, правильно выровненный и инициализированный нулями, при этом ob_refcnt должен быть установлен в 1, а ob_type — в аргумент типа. Если tp_itemsize типа не равен нулю, поле ob_size объекта следует инициализировать значением nitems, а длина выделенного блока памяти должна составлять tp_basicsize + nitems*tp_itemsize, округлённое вверх до ближайшего кратного sizeof(void*); в противном случае nitems не используется, а длина блока должна равняться tp_basicsize.

Эта функция не должна выполнять никакую другую инициализацию экземпляра, даже выделять дополнительную память; это должна делать tp_new.

typedef void (*destructor)(PyObject*)
Часть стабильного ABI.
typedef void (*freefunc)(void*)

См. tp_free.

typedef PyObject *(*newfunc)(PyTypeObject*, PyObject*, PyObject*)
Часть стабильного ABI.

См. tp_new.

typedef int (*initproc)(PyObject*, PyObject*, PyObject*)
Часть стабильного ABI.

См. tp_init.

typedef PyObject *(*reprfunc)(PyObject*)
Часть стабильного ABI.

См. tp_repr.

typedef PyObject *(*getattrfunc)(PyObject *self, char *attr)
Часть стабильного ABI.

Возвращает значение именованного атрибута объекта.

typedef int (*setattrfunc)(PyObject *self, char *attr, PyObject *value)
Часть стабильного ABI.

Устанавливает значение именованного атрибута объекта. Для удаления атрибута аргумент value устанавливается в NULL.

typedef PyObject *(*getattrofunc)(PyObject *self, PyObject *attr)
Часть стабильного ABI.

Возвращает значение именованного атрибута объекта.

См. tp_getattro.

typedef int (*setattrofunc)(PyObject *self, PyObject *attr, PyObject *value)
Часть стабильного ABI.

Устанавливает значение именованного атрибута объекта. Для удаления атрибута аргумент value устанавливается в NULL.

См. tp_setattro.

typedef PyObject *(*descrgetfunc)(PyObject*, PyObject*, PyObject*)
Часть стабильного ABI.

См. tp_descr_get.

typedef int (*descrsetfunc)(PyObject*, PyObject*, PyObject*)
Часть стабильного ABI.

См. tp_descr_set.

typedef Py_hash_t (*hashfunc)(PyObject*)
Часть стабильного ABI.

См. tp_hash.

typedef PyObject *(*richcmpfunc)(PyObject*, PyObject*, int)
Часть стабильного ABI.

См. tp_richcompare.

typedef PyObject *(*getiterfunc)(PyObject*)
Часть стабильного ABI.

См. tp_iter.

typedef PyObject *(*iternextfunc)(PyObject*)
Часть стабильного ABI.

См. tp_iternext.

typedef Py_ssize_t (*lenfunc)(PyObject*)
Часть стабильного ABI.
typedef int (*getbufferproc)(PyObject*, Py_buffer*, int)
Часть стабильного ABI начиная с версии 3.12.
typedef void (*releasebufferproc)(PyObject*, Py_buffer*)
Часть стабильного ABI начиная с версии 3.12.
typedef PyObject *(*unaryfunc)(PyObject*)
Часть стабильного ABI.
typedef PyObject *(*binaryfunc)(PyObject*, PyObject*)
Часть стабильного ABI.
typedef PySendResult (*sendfunc)(PyObject*, PyObject*, PyObject**)

См. am_send.

typedef PyObject *(*ternaryfunc)(PyObject*, PyObject*, PyObject*)
Часть стабильного ABI.
typedef PyObject *(*ssizeargfunc)(PyObject*, Py_ssize_t)
Часть стабильного ABI.
typedef int (*ssizeobjargproc)(PyObject*, Py_ssize_t, PyObject*)
Часть стабильного ABI.
typedef int (*objobjproc)(PyObject*, PyObject*)
Часть стабильного ABI.
typedef int (*objobjargproc)(PyObject*, PyObject*, PyObject*)
Часть стабильного ABI.

Примеры

Ниже приведены простые примеры определений типов Python. Они демонстрируют распространённые случаи, с которыми вы можете столкнуться. Некоторые из них показывают нетривиальные крайние случаи. Дополнительные примеры, практические сведения и руководство см. в разделах Определение типов расширений: руководство и Определение типов расширений: различные темы.

Базовый статический тип:

typedef struct {
    PyObject_HEAD
    const char *data;
} MyObject;

static PyTypeObject MyObject_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "mymod.MyObject",
    .tp_basicsize = sizeof(MyObject),
    .tp_doc = PyDoc_STR("My objects"),
    .tp_new = myobj_new,
    .tp_dealloc = (destructor)myobj_dealloc,
    .tp_repr = (reprfunc)myobj_repr,
};

В старом коде (особенно в исходном коде CPython) также может встречаться более многословный инициализатор:

static PyTypeObject MyObject_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "mymod.MyObject",               /* tp_name */
    sizeof(MyObject),               /* tp_basicsize */
    0,                              /* tp_itemsize */
    (destructor)myobj_dealloc,      /* tp_dealloc */
    0,                              /* tp_vectorcall_offset */
    0,                              /* tp_getattr */
    0,                              /* tp_setattr */
    0,                              /* tp_as_async */
    (reprfunc)myobj_repr,           /* tp_repr */
    0,                              /* tp_as_number */
    0,                              /* tp_as_sequence */
    0,                              /* tp_as_mapping */
    0,                              /* tp_hash */
    0,                              /* tp_call */
    0,                              /* tp_str */
    0,                              /* tp_getattro */
    0,                              /* tp_setattro */
    0,                              /* tp_as_buffer */
    0,                              /* tp_flags */
    PyDoc_STR("My objects"),        /* tp_doc */
    0,                              /* tp_traverse */
    0,                              /* tp_clear */
    0,                              /* tp_richcompare */
    0,                              /* tp_weaklistoffset */
    0,                              /* tp_iter */
    0,                              /* tp_iternext */
    0,                              /* tp_methods */
    0,                              /* tp_members */
    0,                              /* tp_getset */
    0,                              /* tp_base */
    0,                              /* tp_dict */
    0,                              /* tp_descr_get */
    0,                              /* tp_descr_set */
    0,                              /* tp_dictoffset */
    0,                              /* tp_init */
    0,                              /* tp_alloc */
    myobj_new,                      /* tp_new */
};

Тип, поддерживающий слабые ссылки, словари экземпляров и хеширование:

typedef struct {
    PyObject_HEAD
    const char *data;
} MyObject;

static PyTypeObject MyObject_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "mymod.MyObject",
    .tp_basicsize = sizeof(MyObject),
    .tp_doc = PyDoc_STR("My objects"),
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
         Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_DICT |
         Py_TPFLAGS_MANAGED_WEAKREF,
    .tp_new = myobj_new,
    .tp_traverse = (traverseproc)myobj_traverse,
    .tp_clear = (inquiry)myobj_clear,
    .tp_alloc = PyType_GenericNew,
    .tp_dealloc = (destructor)myobj_dealloc,
    .tp_repr = (reprfunc)myobj_repr,
    .tp_hash = (hashfunc)myobj_hash,
    .tp_richcompare = PyBaseObject_Type.tp_richcompare,
};

Подкласс str, который нельзя дополнительно наследовать и нельзя вызывать для создания экземпляров (например, он использует отдельную фабричную функцию), с флагом Py_TPFLAGS_DISALLOW_INSTANTIATION:

typedef struct {
    PyUnicodeObject raw;
    char *extra;
} MyStr;

static PyTypeObject MyStr_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "mymod.MyStr",
    .tp_basicsize = sizeof(MyStr),
    .tp_base = NULL,  // set to &PyUnicode_Type in module init
    .tp_doc = PyDoc_STR("my custom str"),
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
    .tp_repr = (reprfunc)myobj_repr,
};

Самый простой статический тип с экземплярами фиксированной длины:

typedef struct {
    PyObject_HEAD
} MyObject;

static PyTypeObject MyObject_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "mymod.MyObject",
};

Самый простой статический тип с экземплярами переменной длины:

typedef struct {
    PyObject_VAR_HEAD
    const char *data[1];
} MyObject;

static PyTypeObject MyObject_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "mymod.MyObject",
    .tp_basicsize = sizeof(MyObject) - sizeof(char *),
    .tp_itemsize = sizeof(char *),
};

© 2001 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.14/c-api/typeobj.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API