Heap allocated types (created using :c:func:`PyType_FromSpec` or similar),
``PyMemberDef`` may contain definitions for the special members
- ``__dictoffset__`` and ``__weaklistoffset__``, corresponding to
- :c:member:`~PyTypeObject.tp_dictoffset` and
- :c:member:`~PyTypeObject.tp_weaklistoffset` in type objects.
+ ``__dictoffset__``, ``__weaklistoffset__`` and ``__vectorcalloffset__``,
+ corresponding to
+ :c:member:`~PyTypeObject.tp_dictoffset`,
+ :c:member:`~PyTypeObject.tp_weaklistoffset` and
+ :c:member:`~PyTypeObject.tp_vectorcall_offset` in type objects.
These must be defined with ``T_PYSSIZET`` and ``READONLY``, for example::
static PyMemberDef spam_type_members[] = {
* :c:member:`~PyTypeObject.tp_dictoffset`
(see :ref:`PyMemberDef <pymemberdef-offsets>`)
* :c:member:`~PyTypeObject.tp_vectorcall_offset`
+ (see :ref:`PyMemberDef <pymemberdef-offsets>`)
* :c:member:`~PyBufferProcs.bf_getbuffer`
* :c:member:`~PyBufferProcs.bf_releasebuffer`
PyTypeObject *type, *base;
const PyType_Slot *slot;
- Py_ssize_t nmembers, weaklistoffset, dictoffset;
+ Py_ssize_t nmembers, weaklistoffset, dictoffset, vectorcalloffset;
char *res_start;
- nmembers = weaklistoffset = dictoffset = 0;
+ nmembers = weaklistoffset = dictoffset = vectorcalloffset = 0;
for (slot = spec->slots; slot->slot; slot++) {
if (slot->slot == Py_tp_members) {
nmembers = 0;
assert(memb->flags == READONLY);
dictoffset = memb->offset;
}
+ if (strcmp(memb->name, "__vectorcalloffset__") == 0) {
+ // The PyMemberDef must be a Py_ssize_t and readonly
+ assert(memb->type == T_PYSSIZET);
+ assert(memb->flags == READONLY);
+ vectorcalloffset = memb->offset;
+ }
}
}
}
type->tp_dealloc = subtype_dealloc;
}
+ if (vectorcalloffset) {
+ type->tp_vectorcall_offset = vectorcalloffset;
+ }
+
if (PyType_Ready(type) < 0)
goto fail;