bpo-40584: Update PyType_FromModuleAndSpec() to process tp_vectorcall_offset (GH-20026)
This commit is contained in:
parent
ef7973a981
commit
86d69444e7
|
@ -424,9 +424,11 @@ Accessing attributes of extension types
|
||||||
|
|
||||||
Heap allocated types (created using :c:func:`PyType_FromSpec` or similar),
|
Heap allocated types (created using :c:func:`PyType_FromSpec` or similar),
|
||||||
``PyMemberDef`` may contain definitions for the special members
|
``PyMemberDef`` may contain definitions for the special members
|
||||||
``__dictoffset__`` and ``__weaklistoffset__``, corresponding to
|
``__dictoffset__``, ``__weaklistoffset__`` and ``__vectorcalloffset__``,
|
||||||
:c:member:`~PyTypeObject.tp_dictoffset` and
|
corresponding to
|
||||||
:c:member:`~PyTypeObject.tp_weaklistoffset` in type objects.
|
: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::
|
These must be defined with ``T_PYSSIZET`` and ``READONLY``, for example::
|
||||||
|
|
||||||
static PyMemberDef spam_type_members[] = {
|
static PyMemberDef spam_type_members[] = {
|
||||||
|
|
|
@ -228,6 +228,7 @@ The following functions and structs are used to create
|
||||||
* :c:member:`~PyTypeObject.tp_dictoffset`
|
* :c:member:`~PyTypeObject.tp_dictoffset`
|
||||||
(see :ref:`PyMemberDef <pymemberdef-offsets>`)
|
(see :ref:`PyMemberDef <pymemberdef-offsets>`)
|
||||||
* :c:member:`~PyTypeObject.tp_vectorcall_offset`
|
* :c:member:`~PyTypeObject.tp_vectorcall_offset`
|
||||||
|
(see :ref:`PyMemberDef <pymemberdef-offsets>`)
|
||||||
* :c:member:`~PyBufferProcs.bf_getbuffer`
|
* :c:member:`~PyBufferProcs.bf_getbuffer`
|
||||||
* :c:member:`~PyBufferProcs.bf_releasebuffer`
|
* :c:member:`~PyBufferProcs.bf_releasebuffer`
|
||||||
|
|
||||||
|
|
|
@ -2954,10 +2954,10 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
|
||||||
PyTypeObject *type, *base;
|
PyTypeObject *type, *base;
|
||||||
|
|
||||||
const PyType_Slot *slot;
|
const PyType_Slot *slot;
|
||||||
Py_ssize_t nmembers, weaklistoffset, dictoffset;
|
Py_ssize_t nmembers, weaklistoffset, dictoffset, vectorcalloffset;
|
||||||
char *res_start;
|
char *res_start;
|
||||||
|
|
||||||
nmembers = weaklistoffset = dictoffset = 0;
|
nmembers = weaklistoffset = dictoffset = vectorcalloffset = 0;
|
||||||
for (slot = spec->slots; slot->slot; slot++) {
|
for (slot = spec->slots; slot->slot; slot++) {
|
||||||
if (slot->slot == Py_tp_members) {
|
if (slot->slot == Py_tp_members) {
|
||||||
nmembers = 0;
|
nmembers = 0;
|
||||||
|
@ -2975,6 +2975,12 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
|
||||||
assert(memb->flags == READONLY);
|
assert(memb->flags == READONLY);
|
||||||
dictoffset = memb->offset;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3123,6 +3129,10 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
|
||||||
type->tp_dealloc = subtype_dealloc;
|
type->tp_dealloc = subtype_dealloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vectorcalloffset) {
|
||||||
|
type->tp_vectorcall_offset = vectorcalloffset;
|
||||||
|
}
|
||||||
|
|
||||||
if (PyType_Ready(type) < 0)
|
if (PyType_Ready(type) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue