summaryrefslogtreecommitdiffstats
path: root/Doc/c-api
diff options
context:
space:
mode:
authorPetr Viktorin <encukou@gmail.com>2022-08-04 15:19:29 (GMT)
committerGitHub <noreply@github.com>2022-08-04 15:19:29 (GMT)
commit7b370b73055d757ed09c7942f4631256b27fdcb6 (patch)
tree3cdc13e79e82b0f60c49b36b6fbdf72abd4cf52b /Doc/c-api
parenta613fedd6e18e4ab382cf81ec767e1135fc949a7 (diff)
downloadcpython-7b370b73055d757ed09c7942f4631256b27fdcb6.zip
cpython-7b370b73055d757ed09c7942f4631256b27fdcb6.tar.gz
cpython-7b370b73055d757ed09c7942f4631256b27fdcb6.tar.bz2
gh-93274: Make vectorcall safe on mutable classes & inherit it by default (#95437)
Diffstat (limited to 'Doc/c-api')
-rw-r--r--Doc/c-api/call.rst9
-rw-r--r--Doc/c-api/typeobj.rst34
2 files changed, 29 insertions, 14 deletions
diff --git a/Doc/c-api/call.rst b/Doc/c-api/call.rst
index 13ef8b2..11d5c33 100644
--- a/Doc/c-api/call.rst
+++ b/Doc/c-api/call.rst
@@ -57,6 +57,15 @@ This bears repeating:
A class supporting vectorcall **must** also implement
:c:member:`~PyTypeObject.tp_call` with the same semantics.
+.. versionchanged:: 3.12
+
+ The :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class
+ when the class's :py:meth:`~object.__call__` method is reassigned.
+ (This internally sets :c:member:`~PyTypeObject.tp_call` only, and thus
+ may make it behave differently than the vectorcall function.)
+ In earlier Python versions, vectorcall should only be used with
+ :const:`immutable <Py_TPFLAGS_IMMUTABLETYPE>` or static types.
+
A class should not implement vectorcall if that would be slower
than *tp_call*. For example, if the callee needs to convert
the arguments to an args tuple and kwargs dict anyway, then there is no point
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index 7514801..44884ac 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -720,29 +720,29 @@ and :c:type:`PyType_Type` effectively act as defaults.)
with the *vectorcallfunc* function.
This can be done by setting *tp_call* to :c:func:`PyVectorcall_Call`.
- .. warning::
-
- 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.
-
.. versionchanged:: 3.8
Before version 3.8, this slot was named ``tp_print``.
In Python 2.x, it was used for printing to a file.
In Python 3.0 to 3.7, it was unused.
+ .. versionchanged:: 3.12
+
+ Before version 3.12, it was not recommended for
+ :ref:`mutable heap types <heap-types>` to implement the vectorcall
+ protocol.
+ When a user sets :attr:`~type.__call__` in Python code, only *tp_call* is
+ updated, likely making it inconsistent with the vectorcall function.
+ Since 3.12, setting ``__call__`` will disable vectorcall optimization
+ by clearing the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag.
+
**Inheritance:**
This field is always inherited.
However, the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is not
- always inherited. If it's not, then the subclass won't use
+ always inherited. If it's not set, 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 types without the
- :const:`Py_TPFLAGS_IMMUTABLETYPE` flag set (including subclasses defined in
- Python).
.. c:member:: getattrfunc PyTypeObject.tp_getattr
@@ -1178,12 +1178,18 @@ and :c:type:`PyType_Type` effectively act as defaults.)
**Inheritance:**
- This bit is inherited for types with the
- :const:`Py_TPFLAGS_IMMUTABLETYPE` flag set, if
- :c:member:`~PyTypeObject.tp_call` is also inherited.
+ This bit is inherited if :c:member:`~PyTypeObject.tp_call` is also
+ inherited.
.. versionadded:: 3.9
+ .. versionchanged:: 3.12
+
+ This flag is now removed from a class when the class's
+ :py:meth:`~object.__call__` method is reassigned.
+
+ This flag can now be inherited by mutable classes.
+
.. data:: Py_TPFLAGS_IMMUTABLETYPE
This bit is set for type objects that are immutable: type attributes cannot be set nor deleted.