diff options
author | Petr Viktorin <encukou@gmail.com> | 2022-08-04 15:19:29 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-04 15:19:29 (GMT) |
commit | 7b370b73055d757ed09c7942f4631256b27fdcb6 (patch) | |
tree | 3cdc13e79e82b0f60c49b36b6fbdf72abd4cf52b /Doc/c-api | |
parent | a613fedd6e18e4ab382cf81ec767e1135fc949a7 (diff) | |
download | cpython-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.rst | 9 | ||||
-rw-r--r-- | Doc/c-api/typeobj.rst | 34 |
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. |