.. warning::
- It is not recommended for :ref:`heap types <heap-types>` to implement
+ It is not recommended for :ref:`mutable heap types <heap-types>` to implement
the vectorcall protocol.
When a user sets :attr:`__call__` in Python code, only *tp_call* is updated,
likely making it inconsistent with the vectorcall function.
always inherited. If it's not, then the subclass won't use
:ref:`vectorcall <vectorcall>`, except when
:c:func:`PyVectorcall_Call` is explicitly called.
- This is in particular the case for :ref:`heap types <heap-types>`
- (including subclasses defined in Python).
+ This is in particular the case for types without the
+ :const:`Py_TPFLAGS_IMMUTABLETYPE` flag set (including subclasses defined in
+ Python).
.. c:member:: getattrfunc PyTypeObject.tp_getattr
**Inheritance:**
- This flag is never inherited by :ref:`heap types <heap-types>`.
- For extension types, it is inherited whenever
- :c:member:`~PyTypeObject.tp_descr_get` is inherited.
+ This flag is never inherited by types without the
+ :const:`Py_TPFLAGS_IMMUTABLETYPE` flag set. For extension types, it is
+ inherited whenever :c:member:`~PyTypeObject.tp_descr_get` is inherited.
.. XXX Document more flags here?
**Inheritance:**
- This bit is inherited for :ref:`static subtypes <static-types>` if
+ This bit is inherited for types with the
+ :const:`Py_TPFLAGS_IMMUTABLETYPE` flag set, if
:c:member:`~PyTypeObject.tp_call` is also inherited.
- :ref:`Heap types <heap-types>` do not inherit ``Py_TPFLAGS_HAVE_VECTORCALL``.
.. versionadded:: 3.9
(:c:member:`PyTypeObject.tp_traverse`).
(Contributed by Victor Stinner in :issue:`44263`.)
+* Heap types with the :const:`Py_TPFLAGS_IMMUTABLETYPE` flag can now inherit
+ the :pep:`590` vectorcall protocol. Previously, this was only possible for
+ :ref:`static types <static-types>`.
+ (Contributed by Erlend E. Aasland in :issue:`43908`)
+
Deprecated
----------
self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
- # Heap type should not inherit Py_TPFLAGS_METHOD_DESCRIPTOR
+ # Mutable heap types should not inherit Py_TPFLAGS_METHOD_DESCRIPTOR
class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
pass
self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
self.assertTrue(_testcapi.MethodDescriptor2.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
- # Heap type should not inherit Py_TPFLAGS_HAVE_VECTORCALL
+ # Mutable heap types should not inherit Py_TPFLAGS_HAVE_VECTORCALL
class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
pass
self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
--- /dev/null
+Heap types with the :const:`Py_TPFLAGS_IMMUTABLETYPE` flag can now inherit the
+:pep:`590` vectorcall protocol. Previously, this was only possible for
+:ref:`static types <static-types>`. Patch by Erlend E. Aasland.
/* Inherit Py_TPFLAGS_HAVE_VECTORCALL for non-heap types
* if tp_call is not overridden */
if (!type->tp_call &&
- (base->tp_flags & Py_TPFLAGS_HAVE_VECTORCALL) &&
- !(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
+ _PyType_HasFeature(base, Py_TPFLAGS_HAVE_VECTORCALL) &&
+ _PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE))
{
type->tp_flags |= Py_TPFLAGS_HAVE_VECTORCALL;
}
* but only for extension types */
if (base->tp_descr_get &&
type->tp_descr_get == base->tp_descr_get &&
- !(type->tp_flags & Py_TPFLAGS_HEAPTYPE) &&
- (base->tp_flags & Py_TPFLAGS_METHOD_DESCRIPTOR))
+ _PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE) &&
+ _PyType_HasFeature(base, Py_TPFLAGS_METHOD_DESCRIPTOR))
{
type->tp_flags |= Py_TPFLAGS_METHOD_DESCRIPTOR;
}