From e66e3476fc4ee968b612d782fd2724990bf90430 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 27 Aug 2024 15:36:35 +0200 Subject: [PATCH] Documentation changes --- Doc/c-api/type.rst | 13 ++++++------- Doc/c-api/typeobj.rst | 39 ++++++++++++++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index ada8ad3fa65df5..60f881c1964d06 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -492,13 +492,6 @@ The following functions and structs are used to create See :ref:`PyMemberDef documentation ` for details. - .. versionchanged:: 3.14 - - The field :c:member:`~PyTypeObject.tp_vectorcall` can only be set - since Python 3.14. On older versions, use - :c:member:`~PyTypeObject.tp_new` and/or - :c:member:`~PyTypeObject.tp_init`. - The following internal fields cannot be set at all when creating a heap type: @@ -523,6 +516,12 @@ The following functions and structs are used to create :c:member:`~PyBufferProcs.bf_releasebuffer` are now available under the :ref:`limited API `. + .. versionchanged:: 3.14 + + The field :c:member:`~PyTypeObject.tp_vectorcall` can now set + using ``Py_tp_vectorcall``. See the field's documentation + for details. + .. c:member:: void *pfunc The desired value of the slot. In most cases, this is a pointer diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index b7b1418df513c6..061e4431d55e97 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -2137,11 +2137,40 @@ and :c:data:`PyType_Type` effectively act as defaults.) .. c:member:: vectorcallfunc PyTypeObject.tp_vectorcall - Vectorcall function to use for calls of this type object. - In other words, it is used to implement - :ref:`vectorcall ` for ``type.__call__``. - If ``tp_vectorcall`` is ``NULL``, the default call implementation - using :meth:`~object.__new__` and :meth:`~object.__init__` is used. + A :ref:`vectorcall function ` to use for calls of this type + object (rather than instances). + In other words, ``tp_vectorcall`` can be used to optimize ``type.__call__``, + which typically returns a new instance of *type*. + + As with any vectorcall function, if ``tp_vectorcall`` is ``NULL``, + the *tp_call* protocol (``Py_TYPE(type)->tp_call``) is used instead. + + .. note:: + + The :ref:`vectorcall protocol ` requires that the vectorcall + function has the same behavior as the corresponding ``tp_call``. + This means that ``type->tp_vectorcall`` must match the behavior of + :c:expr:`Py_TYPE(type)->tp_call`. + + Specifically, if *type* that uses the default metaclass, + ``type->tp_vectorcall`` must behave the same as + :c:expr:`PyType_Type->tp_call`, which: + + - calls :c:expr:`type->tp_new`, + + - if the result is a subclass of *type*, calls :c:expr:`type->tp_init` + on the result of ``tp_new``, and + + - returns the result of ``tp_new``. + + Typically, ``tp_vectorcall`` is overridden to optimize this process + for specific :c:member:`~PyTypeObject.tp_new` and + :c:member:`~PyTypeObject.tp_init`. + When doing this for user-subclassable types, note that both can be + overridden (using :py:func:`~object.__new__` and + :py:func:`~object.__init__`, respectively). + + **Inheritance:**