Skip to content

Commit 86d6944

Browse files
authored
bpo-40584: Update PyType_FromModuleAndSpec() to process tp_vectorcall_offset (GH-20026)
1 parent ef7973a commit 86d6944

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

Doc/c-api/structures.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -424,9 +424,11 @@ Accessing attributes of extension types
424424
425425
Heap allocated types (created using :c:func:`PyType_FromSpec` or similar),
426426
``PyMemberDef`` may contain definitions for the special members
427-
``__dictoffset__`` and ``__weaklistoffset__``, corresponding to
428-
:c:member:`~PyTypeObject.tp_dictoffset` and
429-
:c:member:`~PyTypeObject.tp_weaklistoffset` in type objects.
427+
``__dictoffset__``, ``__weaklistoffset__`` and ``__vectorcalloffset__``,
428+
corresponding to
429+
:c:member:`~PyTypeObject.tp_dictoffset`,
430+
:c:member:`~PyTypeObject.tp_weaklistoffset` and
431+
:c:member:`~PyTypeObject.tp_vectorcall_offset` in type objects.
430432
These must be defined with ``T_PYSSIZET`` and ``READONLY``, for example::
431433
432434
static PyMemberDef spam_type_members[] = {

Doc/c-api/type.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ The following functions and structs are used to create
228228
* :c:member:`~PyTypeObject.tp_dictoffset`
229229
(see :ref:`PyMemberDef <pymemberdef-offsets>`)
230230
* :c:member:`~PyTypeObject.tp_vectorcall_offset`
231+
(see :ref:`PyMemberDef <pymemberdef-offsets>`)
231232
* :c:member:`~PyBufferProcs.bf_getbuffer`
232233
* :c:member:`~PyBufferProcs.bf_releasebuffer`
233234

Objects/typeobject.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2954,10 +2954,10 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
29542954
PyTypeObject *type, *base;
29552955

29562956
const PyType_Slot *slot;
2957-
Py_ssize_t nmembers, weaklistoffset, dictoffset;
2957+
Py_ssize_t nmembers, weaklistoffset, dictoffset, vectorcalloffset;
29582958
char *res_start;
29592959

2960-
nmembers = weaklistoffset = dictoffset = 0;
2960+
nmembers = weaklistoffset = dictoffset = vectorcalloffset = 0;
29612961
for (slot = spec->slots; slot->slot; slot++) {
29622962
if (slot->slot == Py_tp_members) {
29632963
nmembers = 0;
@@ -2975,6 +2975,12 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
29752975
assert(memb->flags == READONLY);
29762976
dictoffset = memb->offset;
29772977
}
2978+
if (strcmp(memb->name, "__vectorcalloffset__") == 0) {
2979+
// The PyMemberDef must be a Py_ssize_t and readonly
2980+
assert(memb->type == T_PYSSIZET);
2981+
assert(memb->flags == READONLY);
2982+
vectorcalloffset = memb->offset;
2983+
}
29782984
}
29792985
}
29802986
}
@@ -3123,6 +3129,10 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
31233129
type->tp_dealloc = subtype_dealloc;
31243130
}
31253131

3132+
if (vectorcalloffset) {
3133+
type->tp_vectorcall_offset = vectorcalloffset;
3134+
}
3135+
31263136
if (PyType_Ready(type) < 0)
31273137
goto fail;
31283138

0 commit comments

Comments
 (0)