bpo-36974: inherit tp_vectorcall_offset unconditionally (GH-13858) · python/cpython@a8b27e6 (original) (raw)
File tree
4 files changed
lines changed
- Misc/NEWS.d/next/Core and Builtins
4 files changed
lines changed
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -577,9 +577,18 @@ class MethodDescriptorOverridden(_testcapi.MethodDescriptorBase): | ||
577 | 577 | def __call__(self, n): |
578 | 578 | return 'new' |
579 | 579 | |
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 | + | |
580 | 588 | calls += [ |
581 | 589 | (MethodDescriptorHeap(), (0,), {}, True), |
582 | 590 | (MethodDescriptorOverridden(), (0,), {}, 'new'), |
591 | + (MethodDescriptorSuper(), (0,), {}, True), | |
583 | 592 | ] |
584 | 593 | |
585 | 594 | for (func, args, kwargs, expected) in calls: |
Original file line number | Diff line number | Diff 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. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -184,7 +184,7 @@ PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) | ||
184 | 184 | /* get vectorcallfunc as in _PyVectorcall_Function, but without |
185 | 185 | * the _Py_TPFLAGS_HAVE_VECTORCALL check */ |
186 | 186 | Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset; |
187 | -if ((offset <= 0) | | |
187 | +if (offset <= 0) { | |
188 | 188 | PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall", |
189 | 189 | Py_TYPE(callable)->tp_name); |
190 | 190 | return NULL; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -5153,15 +5153,15 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) | ||
5153 | 5153 | COPYSLOT(tp_repr); |
5154 | 5154 | /* tp_hash see tp_richcompare */ |
5155 | 5155 | { |
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 | |
5161 | 5162 | * if tp_call is not overridden */ |
5162 | 5163 | if (!type->tp_call && |
5163 | 5164 | (base->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) && |
5164 | - !(type->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) && | |
5165 | 5165 | !(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) |
5166 | 5166 | { |
5167 | 5167 | type->tp_flags |= _Py_TPFLAGS_HAVE_VECTORCALL; |