mirror of https://github.com/python/cpython
bpo-36974: inherit tp_vectorcall_offset unconditionally (GH-13858)
This commit is contained in:
parent
47fbc4e45b
commit
a8b27e623d
|
@ -577,9 +577,18 @@ class TestPEP590(unittest.TestCase):
|
||||||
def __call__(self, n):
|
def __call__(self, n):
|
||||||
return 'new'
|
return 'new'
|
||||||
|
|
||||||
|
class SuperBase:
|
||||||
|
def __call__(self, *args):
|
||||||
|
return super().__call__(*args)
|
||||||
|
|
||||||
|
class MethodDescriptorSuper(SuperBase, _testcapi.MethodDescriptorBase):
|
||||||
|
def __call__(self, *args):
|
||||||
|
return super().__call__(*args)
|
||||||
|
|
||||||
calls += [
|
calls += [
|
||||||
(MethodDescriptorHeap(), (0,), {}, True),
|
(MethodDescriptorHeap(), (0,), {}, True),
|
||||||
(MethodDescriptorOverridden(), (0,), {}, 'new'),
|
(MethodDescriptorOverridden(), (0,), {}, 'new'),
|
||||||
|
(MethodDescriptorSuper(), (0,), {}, True),
|
||||||
]
|
]
|
||||||
|
|
||||||
for (func, args, kwargs, expected) in calls:
|
for (func, args, kwargs, expected) in calls:
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
The slot ``tp_vectorcall_offset`` is inherited unconditionally to support
|
||||||
|
``super().__call__()`` when the base class uses vectorcall.
|
|
@ -184,7 +184,7 @@ PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs)
|
||||||
/* get vectorcallfunc as in _PyVectorcall_Function, but without
|
/* get vectorcallfunc as in _PyVectorcall_Function, but without
|
||||||
* the _Py_TPFLAGS_HAVE_VECTORCALL check */
|
* the _Py_TPFLAGS_HAVE_VECTORCALL check */
|
||||||
Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset;
|
Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset;
|
||||||
if ((offset <= 0) || (!Py_TYPE(callable)->tp_call)) {
|
if (offset <= 0) {
|
||||||
PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall",
|
PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall",
|
||||||
Py_TYPE(callable)->tp_name);
|
Py_TYPE(callable)->tp_name);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -5153,15 +5153,15 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
|
||||||
COPYSLOT(tp_repr);
|
COPYSLOT(tp_repr);
|
||||||
/* tp_hash see tp_richcompare */
|
/* tp_hash see tp_richcompare */
|
||||||
{
|
{
|
||||||
/* Inherit tp_vectorcall_offset only if tp_call is not overridden */
|
/* Always inherit tp_vectorcall_offset to support PyVectorcall_Call().
|
||||||
if (!type->tp_call) {
|
* If _Py_TPFLAGS_HAVE_VECTORCALL is not inherited, then vectorcall
|
||||||
COPYSLOT(tp_vectorcall_offset);
|
* won't be used automatically. */
|
||||||
}
|
COPYSLOT(tp_vectorcall_offset);
|
||||||
/* Inherit_Py_TPFLAGS_HAVE_VECTORCALL for non-heap types
|
|
||||||
|
/* Inherit _Py_TPFLAGS_HAVE_VECTORCALL for non-heap types
|
||||||
* if tp_call is not overridden */
|
* if tp_call is not overridden */
|
||||||
if (!type->tp_call &&
|
if (!type->tp_call &&
|
||||||
(base->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) &&
|
(base->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) &&
|
||||||
!(type->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) &&
|
|
||||||
!(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
|
!(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
|
||||||
{
|
{
|
||||||
type->tp_flags |= _Py_TPFLAGS_HAVE_VECTORCALL;
|
type->tp_flags |= _Py_TPFLAGS_HAVE_VECTORCALL;
|
||||||
|
|
Loading…
Reference in New Issue