summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErlend Egeberg Aasland <erlend.aasland@innova.no>2021-07-08 10:48:01 (GMT)
committerGitHub <noreply@github.com>2021-07-08 10:48:01 (GMT)
commita3739b207adb5d17e3b53347df05b54b1a8b87f0 (patch)
tree682f352648cabd6de5440fafa8fd4e9f6246f76b
parent15f0fc571c1fbc84b6b74dfeb373ca3d35e4c5d7 (diff)
downloadcpython-a3739b207adb5d17e3b53347df05b54b1a8b87f0.zip
cpython-a3739b207adb5d17e3b53347df05b54b1a8b87f0.tar.gz
cpython-a3739b207adb5d17e3b53347df05b54b1a8b87f0.tar.bz2
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 <vstinner@python.org>
-rw-r--r--Doc/c-api/typeobj.rst17
-rw-r--r--Doc/whatsnew/3.11.rst5
-rw-r--r--Lib/test/test_call.py4
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2021-07-03-00-20-39.bpo-43908.YHuV_s.rst3
-rw-r--r--Objects/typeobject.c8
5 files changed, 23 insertions, 14 deletions
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index ea81115..004cecd 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -710,7 +710,7 @@ and :c:type:`PyType_Type` effectively act as defaults.)
.. 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.
@@ -734,8 +734,9 @@ and :c:type:`PyType_Type` effectively act as defaults.)
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
@@ -1125,9 +1126,9 @@ and :c:type:`PyType_Type` effectively act as defaults.)
**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?
@@ -1172,9 +1173,9 @@ and :c:type:`PyType_Type` effectively act as defaults.)
**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
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index 5b58ef6..bfadda1 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -214,6 +214,11 @@ Porting to Python 3.11
(: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
----------
diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py
index 3f45922..c929ca8 100644
--- a/Lib/test/test_call.py
+++ b/Lib/test/test_call.py
@@ -563,7 +563,7 @@ class TestPEP590(unittest.TestCase):
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)
@@ -574,7 +574,7 @@ class TestPEP590(unittest.TestCase):
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)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-07-03-00-20-39.bpo-43908.YHuV_s.rst b/Misc/NEWS.d/next/Core and Builtins/2021-07-03-00-20-39.bpo-43908.YHuV_s.rst
new file mode 100644
index 0000000..6113d0f
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2021-07-03-00-20-39.bpo-43908.YHuV_s.rst
@@ -0,0 +1,3 @@
+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.
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 116ac14..02ea618 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -5881,8 +5881,8 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
/* 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;
}
@@ -5915,8 +5915,8 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
* 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;
}