Skip to content

Commit a3739b2

Browse files
Erlend Egeberg Aaslandvstinner
Erlend Egeberg Aasland
andauthored
bpo-43908: Immutable types inherit vectorcall (GH-27001)
Heap types with the Py_TPFLAGS_IMMUTABLETYPE flag can now inherit the PEP 590 vectorcall protocol. Previously, this was only possible for static types. Co-authored-by: Victor Stinner <[email protected]>
1 parent 15f0fc5 commit a3739b2

File tree

5 files changed

+23
-14
lines changed

5 files changed

+23
-14
lines changed

Doc/c-api/typeobj.rst

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ and :c:type:`PyType_Type` effectively act as defaults.)
710710

711711
.. warning::
712712

713-
It is not recommended for :ref:`heap types <heap-types>` to implement
713+
It is not recommended for :ref:`mutable heap types <heap-types>` to implement
714714
the vectorcall protocol.
715715
When a user sets :attr:`__call__` in Python code, only *tp_call* is updated,
716716
likely making it inconsistent with the vectorcall function.
@@ -734,8 +734,9 @@ and :c:type:`PyType_Type` effectively act as defaults.)
734734
always inherited. If it's not, then the subclass won't use
735735
:ref:`vectorcall <vectorcall>`, except when
736736
:c:func:`PyVectorcall_Call` is explicitly called.
737-
This is in particular the case for :ref:`heap types <heap-types>`
738-
(including subclasses defined in Python).
737+
This is in particular the case for types without the
738+
:const:`Py_TPFLAGS_IMMUTABLETYPE` flag set (including subclasses defined in
739+
Python).
739740

740741

741742
.. c:member:: getattrfunc PyTypeObject.tp_getattr
@@ -1125,9 +1126,9 @@ and :c:type:`PyType_Type` effectively act as defaults.)
11251126

11261127
**Inheritance:**
11271128

1128-
This flag is never inherited by :ref:`heap types <heap-types>`.
1129-
For extension types, it is inherited whenever
1130-
:c:member:`~PyTypeObject.tp_descr_get` is inherited.
1129+
This flag is never inherited by types without the
1130+
:const:`Py_TPFLAGS_IMMUTABLETYPE` flag set. For extension types, it is
1131+
inherited whenever :c:member:`~PyTypeObject.tp_descr_get` is inherited.
11311132

11321133

11331134
.. XXX Document more flags here?
@@ -1172,9 +1173,9 @@ and :c:type:`PyType_Type` effectively act as defaults.)
11721173

11731174
**Inheritance:**
11741175

1175-
This bit is inherited for :ref:`static subtypes <static-types>` if
1176+
This bit is inherited for types with the
1177+
:const:`Py_TPFLAGS_IMMUTABLETYPE` flag set, if
11761178
:c:member:`~PyTypeObject.tp_call` is also inherited.
1177-
:ref:`Heap types <heap-types>` do not inherit ``Py_TPFLAGS_HAVE_VECTORCALL``.
11781179

11791180
.. versionadded:: 3.9
11801181

Doc/whatsnew/3.11.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,11 @@ Porting to Python 3.11
214214
(:c:member:`PyTypeObject.tp_traverse`).
215215
(Contributed by Victor Stinner in :issue:`44263`.)
216216

217+
* Heap types with the :const:`Py_TPFLAGS_IMMUTABLETYPE` flag can now inherit
218+
the :pep:`590` vectorcall protocol. Previously, this was only possible for
219+
:ref:`static types <static-types>`.
220+
(Contributed by Erlend E. Aasland in :issue:`43908`)
221+
217222
Deprecated
218223
----------
219224

Lib/test/test_call.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ def test_method_descriptor_flag(self):
563563
self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
564564
self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
565565

566-
# Heap type should not inherit Py_TPFLAGS_METHOD_DESCRIPTOR
566+
# Mutable heap types should not inherit Py_TPFLAGS_METHOD_DESCRIPTOR
567567
class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
568568
pass
569569
self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
@@ -574,7 +574,7 @@ def test_vectorcall_flag(self):
574574
self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
575575
self.assertTrue(_testcapi.MethodDescriptor2.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
576576

577-
# Heap type should not inherit Py_TPFLAGS_HAVE_VECTORCALL
577+
# Mutable heap types should not inherit Py_TPFLAGS_HAVE_VECTORCALL
578578
class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
579579
pass
580580
self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Heap types with the :const:`Py_TPFLAGS_IMMUTABLETYPE` flag can now inherit the
2+
:pep:`590` vectorcall protocol. Previously, this was only possible for
3+
:ref:`static types <static-types>`. Patch by Erlend E. Aasland.

Objects/typeobject.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5881,8 +5881,8 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
58815881
/* Inherit Py_TPFLAGS_HAVE_VECTORCALL for non-heap types
58825882
* if tp_call is not overridden */
58835883
if (!type->tp_call &&
5884-
(base->tp_flags & Py_TPFLAGS_HAVE_VECTORCALL) &&
5885-
!(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
5884+
_PyType_HasFeature(base, Py_TPFLAGS_HAVE_VECTORCALL) &&
5885+
_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE))
58865886
{
58875887
type->tp_flags |= Py_TPFLAGS_HAVE_VECTORCALL;
58885888
}
@@ -5915,8 +5915,8 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
59155915
* but only for extension types */
59165916
if (base->tp_descr_get &&
59175917
type->tp_descr_get == base->tp_descr_get &&
5918-
!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) &&
5919-
(base->tp_flags & Py_TPFLAGS_METHOD_DESCRIPTOR))
5918+
_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE) &&
5919+
_PyType_HasFeature(base, Py_TPFLAGS_METHOD_DESCRIPTOR))
59205920
{
59215921
type->tp_flags |= Py_TPFLAGS_METHOD_DESCRIPTOR;
59225922
}

0 commit comments

Comments
 (0)