Skip to content

Commit a8b27e6

Browse files
jdemeyerencukou
authored andcommitted
bpo-36974: inherit tp_vectorcall_offset unconditionally (GH-13858)
1 parent 47fbc4e commit a8b27e6

File tree

4 files changed

+18
-7
lines changed

4 files changed

+18
-7
lines changed

Lib/test/test_call.py

+9
Original file line numberDiff line numberDiff line change
@@ -577,9 +577,18 @@ class MethodDescriptorOverridden(_testcapi.MethodDescriptorBase):
577577
def __call__(self, n):
578578
return 'new'
579579

580+
class SuperBase:
581+
def __call__(self, *args):
582+
return super().__call__(*args)
583+
584+
class MethodDescriptorSuper(SuperBase, _testcapi.MethodDescriptorBase):
585+
def __call__(self, *args):
586+
return super().__call__(*args)
587+
580588
calls += [
581589
(MethodDescriptorHeap(), (0,), {}, True),
582590
(MethodDescriptorOverridden(), (0,), {}, 'new'),
591+
(MethodDescriptorSuper(), (0,), {}, True),
583592
]
584593

585594
for (func, args, kwargs, expected) in calls:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The slot ``tp_vectorcall_offset`` is inherited unconditionally to support
2+
``super().__call__()`` when the base class uses vectorcall.

Objects/call.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs)
184184
/* get vectorcallfunc as in _PyVectorcall_Function, but without
185185
* the _Py_TPFLAGS_HAVE_VECTORCALL check */
186186
Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset;
187-
if ((offset <= 0) || (!Py_TYPE(callable)->tp_call)) {
187+
if (offset <= 0) {
188188
PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall",
189189
Py_TYPE(callable)->tp_name);
190190
return NULL;

Objects/typeobject.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -5153,15 +5153,15 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
51535153
COPYSLOT(tp_repr);
51545154
/* tp_hash see tp_richcompare */
51555155
{
5156-
/* Inherit tp_vectorcall_offset only if tp_call is not overridden */
5157-
if (!type->tp_call) {
5158-
COPYSLOT(tp_vectorcall_offset);
5159-
}
5160-
/* Inherit_Py_TPFLAGS_HAVE_VECTORCALL for non-heap types
5156+
/* Always inherit tp_vectorcall_offset to support PyVectorcall_Call().
5157+
* If _Py_TPFLAGS_HAVE_VECTORCALL is not inherited, then vectorcall
5158+
* won't be used automatically. */
5159+
COPYSLOT(tp_vectorcall_offset);
5160+
5161+
/* Inherit _Py_TPFLAGS_HAVE_VECTORCALL for non-heap types
51615162
* if tp_call is not overridden */
51625163
if (!type->tp_call &&
51635164
(base->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) &&
5164-
!(type->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) &&
51655165
!(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
51665166
{
51675167
type->tp_flags |= _Py_TPFLAGS_HAVE_VECTORCALL;

0 commit comments

Comments
 (0)