Skip to content

Commit 4782dd1

Browse files
committed
bpo-36974: inherit tp_vectorcall_offset unconditionally
1 parent e119b3d commit 4782dd1

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
@@ -176,7 +176,7 @@ PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs)
176176
/* get vectorcallfunc as in _PyVectorcall_Function, but without
177177
* the _Py_TPFLAGS_HAVE_VECTORCALL check */
178178
Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset;
179-
if ((offset <= 0) || (!Py_TYPE(callable)->tp_call)) {
179+
if (offset <= 0) {
180180
PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall",
181181
Py_TYPE(callable)->tp_name);
182182
return NULL;

Objects/typeobject.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -5148,15 +5148,15 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
51485148
COPYSLOT(tp_repr);
51495149
/* tp_hash see tp_richcompare */
51505150
{
5151-
/* Inherit tp_vectorcall_offset only if tp_call is not overridden */
5152-
if (!type->tp_call) {
5153-
COPYSLOT(tp_vectorcall_offset);
5154-
}
5155-
/* Inherit_Py_TPFLAGS_HAVE_VECTORCALL for non-heap types
5151+
/* Always inherit tp_vectorcall_offset to support PyVectorcall_Call().
5152+
* If _Py_TPFLAGS_HAVE_VECTORCALL is not inherited, then vectorcall
5153+
* won't be used automatically. */
5154+
COPYSLOT(tp_vectorcall_offset);
5155+
5156+
/* Inherit _Py_TPFLAGS_HAVE_VECTORCALL for non-heap types
51565157
* if tp_call is not overridden */
51575158
if (!type->tp_call &&
51585159
(base->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) &&
5159-
!(type->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) &&
51605160
!(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
51615161
{
51625162
type->tp_flags |= _Py_TPFLAGS_HAVE_VECTORCALL;

0 commit comments

Comments
 (0)