bpo-36974: document PEP 590 (GH-13450)
This commit is contained in:
parent
82eac26a73
commit
9e3e06e582
|
@ -335,6 +335,83 @@ Object Protocol
|
||||||
*NULL* on failure.
|
*NULL* on failure.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: PyObject* _PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)
|
||||||
|
|
||||||
|
Call a callable Python object *callable*, using
|
||||||
|
:c:data:`vectorcall <PyTypeObject.tp_vectorcall_offset>` if possible.
|
||||||
|
|
||||||
|
*args* is a C array with the positional arguments.
|
||||||
|
|
||||||
|
*nargsf* is the number of positional arguments plus optionally the flag
|
||||||
|
:const:`PY_VECTORCALL_ARGUMENTS_OFFSET` (see below).
|
||||||
|
To get actual number of arguments, use
|
||||||
|
:c:func:`PyVectorcall_NARGS(nargsf) <PyVectorcall_NARGS>`.
|
||||||
|
|
||||||
|
*kwnames* can be either NULL (no keyword arguments) or a tuple of keyword
|
||||||
|
names. In the latter case, the values of the keyword arguments are stored
|
||||||
|
in *args* after the positional arguments.
|
||||||
|
The number of keyword arguments does not influence *nargsf*.
|
||||||
|
|
||||||
|
*kwnames* must contain only objects of type ``str`` (not a subclass),
|
||||||
|
and all keys must be unique.
|
||||||
|
|
||||||
|
Return the result of the call on success, or *NULL* on failure.
|
||||||
|
|
||||||
|
This uses the vectorcall protocol if the callable supports it;
|
||||||
|
otherwise, the arguments are converted to use
|
||||||
|
:c:member:`~PyTypeObject.tp_call`.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This function is provisional and expected to become public in Python 3.9,
|
||||||
|
with a different name and, possibly, changed semantics.
|
||||||
|
If you use the function, plan for updating your code for Python 3.9.
|
||||||
|
|
||||||
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
|
.. c:var:: PY_VECTORCALL_ARGUMENTS_OFFSET
|
||||||
|
|
||||||
|
If set in a vectorcall *nargsf* argument, the callee is allowed to
|
||||||
|
temporarily change ``args[-1]``. In other words, *args* points to
|
||||||
|
argument 1 (not 0) in the allocated vector.
|
||||||
|
The callee must restore the value of ``args[-1]`` before returning.
|
||||||
|
|
||||||
|
Whenever they can do so cheaply (without additional allocation), callers
|
||||||
|
are encouraged to use :const:`PY_VECTORCALL_ARGUMENTS_OFFSET`.
|
||||||
|
Doing so will allow callables such as bound methods to make their onward
|
||||||
|
calls (which include a prepended *self* argument) cheaply.
|
||||||
|
|
||||||
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
|
.. c:function:: Py_ssize_t PyVectorcall_NARGS(size_t nargsf)
|
||||||
|
|
||||||
|
Given a vectorcall *nargsf* argument, return the actual number of
|
||||||
|
arguments.
|
||||||
|
Currently equivalent to ``nargsf & ~PY_VECTORCALL_ARGUMENTS_OFFSET``.
|
||||||
|
|
||||||
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
|
.. c:function:: PyObject* _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwdict)
|
||||||
|
|
||||||
|
Same as :c:func:`_PyObject_Vectorcall` except that the keyword arguments
|
||||||
|
are passed as a dictionary in *kwdict*. This may be *NULL* if there
|
||||||
|
are no keyword arguments.
|
||||||
|
|
||||||
|
For callables supporting :c:data:`vectorcall <PyTypeObject.tp_vectorcall_offset>`,
|
||||||
|
the arguments are internally converted to the vectorcall convention.
|
||||||
|
Therefore, this function adds some overhead compared to
|
||||||
|
:c:func:`_PyObject_Vectorcall`.
|
||||||
|
It should only be used if the caller already has a dictionary ready to use.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This function is provisional and expected to become public in Python 3.9,
|
||||||
|
with a different name and, possibly, changed semantics.
|
||||||
|
If you use the function, plan for updating your code for Python 3.9.
|
||||||
|
|
||||||
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
|
|
||||||
.. c:function:: Py_hash_t PyObject_Hash(PyObject *o)
|
.. c:function:: Py_hash_t PyObject_Hash(PyObject *o)
|
||||||
|
|
||||||
.. index:: builtin: hash
|
.. index:: builtin: hash
|
||||||
|
|
|
@ -36,115 +36,115 @@ Quick Reference
|
||||||
.. table::
|
.. table::
|
||||||
:widths: 18,18,18,1,1,1,1
|
:widths: 18,18,18,1,1,1,1
|
||||||
|
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---------------+
|
+------------------------------------------------+-----------------------------------+-------------------+---------------+
|
||||||
| PyTypeObject Slot [#slots]_ | :ref:`Type <slot-typedefs-table>` | special | Info [#cols]_ |
|
| PyTypeObject Slot [#slots]_ | :ref:`Type <slot-typedefs-table>` | special | Info [#cols]_ |
|
||||||
| | | methods/attrs +---+---+---+---+
|
| | | methods/attrs +---+---+---+---+
|
||||||
| | | | O | T | D | I |
|
| | | | O | T | D | I |
|
||||||
+=============================================+===================================+===================+===+===+===+===+
|
+================================================+===================================+===================+===+===+===+===+
|
||||||
| <R> :c:member:`~PyTypeObject.tp_name` | const char * | __name__ | X | X | | |
|
| <R> :c:member:`~PyTypeObject.tp_name` | const char * | __name__ | X | X | | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_basicsize` | Py_ssize_t | | X | X | | X |
|
| :c:member:`~PyTypeObject.tp_basicsize` | Py_ssize_t | | X | X | | X |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_itemsize` | Py_ssize_t | | | X | | X |
|
| :c:member:`~PyTypeObject.tp_itemsize` | Py_ssize_t | | | X | | X |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_dealloc` | :c:type:`destructor` | | X | X | | X |
|
| :c:member:`~PyTypeObject.tp_dealloc` | :c:type:`destructor` | | X | X | | X |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| (:c:member:`~PyTypeObject.tp_print`) | |
|
| :c:member:`~PyTypeObject.tp_vectorcall_offset` | Py_ssize_t | | | | | ? |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| (:c:member:`~PyTypeObject.tp_getattr`) | :c:type:`getattrfunc` | __getattribute__, | | | | G |
|
| (:c:member:`~PyTypeObject.tp_getattr`) | :c:type:`getattrfunc` | __getattribute__, | | | | G |
|
||||||
| | | __getattr__ | | | | |
|
| | | __getattr__ | | | | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| (:c:member:`~PyTypeObject.tp_setattr`) | :c:type:`setattrfunc` | __setattr__, | | | | G |
|
| (:c:member:`~PyTypeObject.tp_setattr`) | :c:type:`setattrfunc` | __setattr__, | | | | G |
|
||||||
| | | __delattr__ | | | | |
|
| | | __delattr__ | | | | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_as_async` | :c:type:`PyAsyncMethods` * | :ref:`sub-slots` | | | | % |
|
| :c:member:`~PyTypeObject.tp_as_async` | :c:type:`PyAsyncMethods` * | :ref:`sub-slots` | | | | % |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_repr` | :c:type:`reprfunc` | __repr__ | X | X | | X |
|
| :c:member:`~PyTypeObject.tp_repr` | :c:type:`reprfunc` | __repr__ | X | X | | X |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_as_number` | :c:type:`PyNumberMethods` * | :ref:`sub-slots` | | | | % |
|
| :c:member:`~PyTypeObject.tp_as_number` | :c:type:`PyNumberMethods` * | :ref:`sub-slots` | | | | % |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_as_sequence` | :c:type:`PySequenceMethods` * | :ref:`sub-slots` | | | | % |
|
| :c:member:`~PyTypeObject.tp_as_sequence` | :c:type:`PySequenceMethods` * | :ref:`sub-slots` | | | | % |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_as_mapping` | :c:type:`PyMappingMethods` * | :ref:`sub-slots` | | | | % |
|
| :c:member:`~PyTypeObject.tp_as_mapping` | :c:type:`PyMappingMethods` * | :ref:`sub-slots` | | | | % |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_hash` | :c:type:`hashfunc` | __hash__ | X | | | G |
|
| :c:member:`~PyTypeObject.tp_hash` | :c:type:`hashfunc` | __hash__ | X | | | G |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_call` | :c:type:`ternaryfunc` | __call__ | | X | | X |
|
| :c:member:`~PyTypeObject.tp_call` | :c:type:`ternaryfunc` | __call__ | | X | | X |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_str` | :c:type:`reprfunc` | __str__ | X | | | X |
|
| :c:member:`~PyTypeObject.tp_str` | :c:type:`reprfunc` | __str__ | X | | | X |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_getattro` | :c:type:`getattrofunc` | __getattribute__, | X | X | | G |
|
| :c:member:`~PyTypeObject.tp_getattro` | :c:type:`getattrofunc` | __getattribute__, | X | X | | G |
|
||||||
| | | __getattr__ | | | | |
|
| | | __getattr__ | | | | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_setattro` | :c:type:`setattrofunc` | __setattr__, | X | X | | G |
|
| :c:member:`~PyTypeObject.tp_setattro` | :c:type:`setattrofunc` | __setattr__, | X | X | | G |
|
||||||
| | | __delattr__ | | | | |
|
| | | __delattr__ | | | | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_as_buffer` | :c:type:`PyBufferProcs` * | | | | | % |
|
| :c:member:`~PyTypeObject.tp_as_buffer` | :c:type:`PyBufferProcs` * | | | | | % |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_flags` | unsigned long | | X | X | | ? |
|
| :c:member:`~PyTypeObject.tp_flags` | unsigned long | | X | X | | ? |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_doc` | const char * | __doc__ | X | X | | |
|
| :c:member:`~PyTypeObject.tp_doc` | const char * | __doc__ | X | X | | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_traverse` | :c:type:`traverseproc` | | | X | | G |
|
| :c:member:`~PyTypeObject.tp_traverse` | :c:type:`traverseproc` | | | X | | G |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_clear` | :c:type:`inquiry` | | | X | | G |
|
| :c:member:`~PyTypeObject.tp_clear` | :c:type:`inquiry` | | | X | | G |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_richcompare` | :c:type:`richcmpfunc` | __lt__, | X | | | G |
|
| :c:member:`~PyTypeObject.tp_richcompare` | :c:type:`richcmpfunc` | __lt__, | X | | | G |
|
||||||
| | | __le__, | | | | |
|
| | | __le__, | | | | |
|
||||||
| | | __eq__, | | | | |
|
| | | __eq__, | | | | |
|
||||||
| | | __ne__, | | | | |
|
| | | __ne__, | | | | |
|
||||||
| | | __gt__, | | | | |
|
| | | __gt__, | | | | |
|
||||||
| | | __ge__ | | | | |
|
| | | __ge__ | | | | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_weaklistoffset` | Py_ssize_t | | | X | | ? |
|
| :c:member:`~PyTypeObject.tp_weaklistoffset` | Py_ssize_t | | | X | | ? |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_iter` | :c:type:`getiterfunc` | __iter__ | | | | X |
|
| :c:member:`~PyTypeObject.tp_iter` | :c:type:`getiterfunc` | __iter__ | | | | X |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_iternext` | :c:type:`iternextfunc` | __next__ | | | | X |
|
| :c:member:`~PyTypeObject.tp_iternext` | :c:type:`iternextfunc` | __next__ | | | | X |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_methods` | :c:type:`PyMethodDef` [] | | X | X | | |
|
| :c:member:`~PyTypeObject.tp_methods` | :c:type:`PyMethodDef` [] | | X | X | | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_members` | :c:type:`PyMemberDef` [] | | | X | | |
|
| :c:member:`~PyTypeObject.tp_members` | :c:type:`PyMemberDef` [] | | | X | | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_getset` | :c:type:`PyGetSetDef` [] | | X | X | | |
|
| :c:member:`~PyTypeObject.tp_getset` | :c:type:`PyGetSetDef` [] | | X | X | | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_base` | :c:type:`PyTypeObject` * | __base__ | | | X | |
|
| :c:member:`~PyTypeObject.tp_base` | :c:type:`PyTypeObject` * | __base__ | | | X | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_dict` | :c:type:`PyObject` * | __dict__ | | | ? | |
|
| :c:member:`~PyTypeObject.tp_dict` | :c:type:`PyObject` * | __dict__ | | | ? | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_descr_get` | :c:type:`descrgetfunc` | __get__ | | | | X |
|
| :c:member:`~PyTypeObject.tp_descr_get` | :c:type:`descrgetfunc` | __get__ | | | | X |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_descr_set` | :c:type:`descrsetfunc` | __set__, | | | | X |
|
| :c:member:`~PyTypeObject.tp_descr_set` | :c:type:`descrsetfunc` | __set__, | | | | X |
|
||||||
| | | __delete__ | | | | |
|
| | | __delete__ | | | | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_dictoffset` | Py_ssize_t | | | X | | ? |
|
| :c:member:`~PyTypeObject.tp_dictoffset` | Py_ssize_t | | | X | | ? |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_init` | :c:type:`initproc` | __init__ | X | X | | X |
|
| :c:member:`~PyTypeObject.tp_init` | :c:type:`initproc` | __init__ | X | X | | X |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_alloc` | :c:type:`allocfunc` | | X | | ? | ? |
|
| :c:member:`~PyTypeObject.tp_alloc` | :c:type:`allocfunc` | | X | | ? | ? |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_new` | :c:type:`newfunc` | __new__ | X | X | ? | ? |
|
| :c:member:`~PyTypeObject.tp_new` | :c:type:`newfunc` | __new__ | X | X | ? | ? |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_free` | :c:type:`freefunc` | | X | X | ? | ? |
|
| :c:member:`~PyTypeObject.tp_free` | :c:type:`freefunc` | | X | X | ? | ? |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_is_gc` | :c:type:`inquiry` | | | X | | X |
|
| :c:member:`~PyTypeObject.tp_is_gc` | :c:type:`inquiry` | | | X | | X |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| <:c:member:`~PyTypeObject.tp_bases`> | :c:type:`PyObject` * | __bases__ | | | ~ | |
|
| <:c:member:`~PyTypeObject.tp_bases`> | :c:type:`PyObject` * | __bases__ | | | ~ | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| <:c:member:`~PyTypeObject.tp_mro`> | :c:type:`PyObject` * | __mro__ | | | ~ | |
|
| <:c:member:`~PyTypeObject.tp_mro`> | :c:type:`PyObject` * | __mro__ | | | ~ | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| [:c:member:`~PyTypeObject.tp_cache`] | :c:type:`PyObject` * | | | | |
|
| [:c:member:`~PyTypeObject.tp_cache`] | :c:type:`PyObject` * | | | | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| [:c:member:`~PyTypeObject.tp_subclasses`] | :c:type:`PyObject` * | __subclasses__ | | | |
|
| [:c:member:`~PyTypeObject.tp_subclasses`] | :c:type:`PyObject` * | __subclasses__ | | | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| [:c:member:`~PyTypeObject.tp_weaklist`] | :c:type:`PyObject` * | | | | |
|
| [:c:member:`~PyTypeObject.tp_weaklist`] | :c:type:`PyObject` * | | | | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| (:c:member:`~PyTypeObject.tp_del`) | :c:type:`destructor` | | | | | |
|
| (:c:member:`~PyTypeObject.tp_del`) | :c:type:`destructor` | | | | | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| [:c:member:`~PyTypeObject.tp_version_tag`] | unsigned int | | | | |
|
| [:c:member:`~PyTypeObject.tp_version_tag`] | unsigned int | | | | |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
| :c:member:`~PyTypeObject.tp_finalize` | :c:type:`destructor` | __del__ | | | | X |
|
| :c:member:`~PyTypeObject.tp_finalize` | :c:type:`destructor` | __del__ | | | | X |
|
||||||
+---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
|
||||||
|
|
||||||
If :const:`COUNT_ALLOCS` is defined then the following (internal-only)
|
If :const:`COUNT_ALLOCS` is defined then the following (internal-only)
|
||||||
fields exist as well:
|
fields exist as well:
|
||||||
|
@ -364,12 +364,6 @@ slot typedefs
|
||||||
+-----------------------------+-----------------------------+----------------------+
|
+-----------------------------+-----------------------------+----------------------+
|
||||||
| :c:type:`reprfunc` | :c:type:`PyObject` * | :c:type:`PyObject` * |
|
| :c:type:`reprfunc` | :c:type:`PyObject` * | :c:type:`PyObject` * |
|
||||||
+-----------------------------+-----------------------------+----------------------+
|
+-----------------------------+-----------------------------+----------------------+
|
||||||
| :c:type:`printfunc` | .. line-block:: | int |
|
|
||||||
| | | |
|
|
||||||
| | :c:type:`PyObject` * | |
|
|
||||||
| | FILE * | |
|
|
||||||
| | int | |
|
|
||||||
+-----------------------------+-----------------------------+----------------------+
|
|
||||||
| :c:type:`getattrfunc` | .. line-block:: | :c:type:`PyObject` * |
|
| :c:type:`getattrfunc` | .. line-block:: | :c:type:`PyObject` * |
|
||||||
| | | |
|
| | | |
|
||||||
| | :c:type:`PyObject` * | |
|
| | :c:type:`PyObject` * | |
|
||||||
|
@ -675,9 +669,66 @@ and :c:type:`PyType_Type` effectively act as defaults.)
|
||||||
This field is inherited by subtypes.
|
This field is inherited by subtypes.
|
||||||
|
|
||||||
|
|
||||||
.. c:member:: printfunc PyTypeObject.tp_print
|
.. c:member:: Py_ssize_t PyTypeObject.tp_vectorcall_offset
|
||||||
|
|
||||||
Reserved slot, formerly used for print formatting in Python 2.x.
|
An optional offset to a per-instance function that implements calling
|
||||||
|
the object using the *vectorcall* protocol, a more efficient alternative
|
||||||
|
of the simpler :c:member:`~PyTypeObject.tp_call`.
|
||||||
|
|
||||||
|
This field is only used if the flag :const:`_Py_TPFLAGS_HAVE_VECTORCALL`
|
||||||
|
is set. If so, this must be a positive integer containing the offset in the
|
||||||
|
instance of a :c:type:`vectorcallfunc` pointer.
|
||||||
|
The signature is the same as for :c:func:`_PyObject_Vectorcall`::
|
||||||
|
|
||||||
|
PyObject *vectorcallfunc(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)
|
||||||
|
|
||||||
|
The *vectorcallfunc* pointer may be zero, in which case the instance behaves
|
||||||
|
as if :const:`_Py_TPFLAGS_HAVE_VECTORCALL` was not set: calling the instance
|
||||||
|
falls back to :c:member:`~PyTypeObject.tp_call`.
|
||||||
|
|
||||||
|
Any class that sets ``_Py_TPFLAGS_HAVE_VECTORCALL`` must also set
|
||||||
|
:c:member:`~PyTypeObject.tp_call` and make sure its behaviour is consistent
|
||||||
|
with the *vectorcallfunc* function.
|
||||||
|
This can be done by setting *tp_call* to ``PyVectorcall_Call``:
|
||||||
|
|
||||||
|
.. c:function:: PyObject *PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict)
|
||||||
|
|
||||||
|
Call *callable*'s *vectorcallfunc* with positional and keyword
|
||||||
|
arguments given in a tuple and dict, respectively.
|
||||||
|
|
||||||
|
This function is intended to be used in the ``tp_call`` slot.
|
||||||
|
It does not fall back to ``tp_call`` and it currently does not check the
|
||||||
|
``_Py_TPFLAGS_HAVE_VECTORCALL`` flag.
|
||||||
|
To call an object, use one of the :c:func:`PyObject_Call <PyObject_Call>`
|
||||||
|
functions instead.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
It is not recommended for :ref:`heap types <heap-types>` to implement
|
||||||
|
the vectorcall protocol.
|
||||||
|
When a user sets ``__call__`` in Python code, only ``tp_call`` is updated,
|
||||||
|
possibly making it inconsistent with the vectorcall function.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The semantics of the ``tp_vectorcall_offset`` slot are provisional and
|
||||||
|
expected to be finalized in Python 3.9.
|
||||||
|
If you use vectorcall, plan for updating your code for Python 3.9.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.8
|
||||||
|
|
||||||
|
This slot was used for print formatting in Python 2.x.
|
||||||
|
In Python 3.0 to 3.7, it was reserved and named ``tp_print``.
|
||||||
|
|
||||||
|
**Inheritance:**
|
||||||
|
|
||||||
|
This field is inherited by subtypes together with
|
||||||
|
:c:member:`~PyTypeObject.tp_call`: a subtype inherits
|
||||||
|
:c:member:`~PyTypeObject.tp_vectorcall_offset` from its base type when
|
||||||
|
the subtype’s :c:member:`~PyTypeObject.tp_call` is NULL.
|
||||||
|
|
||||||
|
Note that `heap types`_ (including subclasses defined in Python) do not
|
||||||
|
inherit the :const:`_Py_TPFLAGS_HAVE_VECTORCALL` flag.
|
||||||
|
|
||||||
|
|
||||||
.. c:member:: getattrfunc PyTypeObject.tp_getattr
|
.. c:member:: getattrfunc PyTypeObject.tp_getattr
|
||||||
|
@ -1104,6 +1155,28 @@ and :c:type:`PyType_Type` effectively act as defaults.)
|
||||||
:c:member:`~PyTypeObject.tp_finalize` slot is always present in the
|
:c:member:`~PyTypeObject.tp_finalize` slot is always present in the
|
||||||
type structure.
|
type structure.
|
||||||
|
|
||||||
|
.. data:: _Py_TPFLAGS_HAVE_VECTORCALL
|
||||||
|
|
||||||
|
This bit is set when the class implements the vectorcall protocol.
|
||||||
|
See :c:member:`~PyTypeObject.tp_vectorcall_offset` for details.
|
||||||
|
|
||||||
|
**Inheritance:**
|
||||||
|
|
||||||
|
This bit is set on *static* subtypes if ``tp_flags`` is not overridden:
|
||||||
|
a subtype inherits ``_Py_TPFLAGS_HAVE_VECTORCALL`` from its base type
|
||||||
|
when the subtype’s :c:member:`~PyTypeObject.tp_call` is NULL
|
||||||
|
and the subtype's ``Py_TPFLAGS_HEAPTYPE`` is not set.
|
||||||
|
|
||||||
|
`Heap types`_ do not inherit ``_Py_TPFLAGS_HAVE_VECTORCALL``.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This flag is provisional and expected to become public in Python 3.9,
|
||||||
|
with a different name and, possibly, changed semantics.
|
||||||
|
If you use vectorcall, plan for updating your code for Python 3.9.
|
||||||
|
|
||||||
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
|
|
||||||
.. c:member:: const char* PyTypeObject.tp_doc
|
.. c:member:: const char* PyTypeObject.tp_doc
|
||||||
|
|
||||||
|
@ -2286,6 +2359,14 @@ Slot Type typedefs
|
||||||
|
|
||||||
.. c:type:: void (*destructor)(PyObject *)
|
.. c:type:: void (*destructor)(PyObject *)
|
||||||
|
|
||||||
|
.. c:type:: PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)
|
||||||
|
|
||||||
|
See :c:member:`~PyTypeObject.tp_vectorcall_offset`.
|
||||||
|
|
||||||
|
Arguments to ``vectorcallfunc`` are the same as for :c:func:`_PyObject_Vectorcall`.
|
||||||
|
|
||||||
|
.. versionadded:: 3.8
|
||||||
|
|
||||||
.. c:type:: void (*freefunc)(void *)
|
.. c:type:: void (*freefunc)(void *)
|
||||||
|
|
||||||
See :c:member:`~PyTypeObject.tp_free`.
|
See :c:member:`~PyTypeObject.tp_free`.
|
||||||
|
@ -2302,10 +2383,6 @@ Slot Type typedefs
|
||||||
|
|
||||||
See :c:member:`~PyTypeObject.tp_repr`.
|
See :c:member:`~PyTypeObject.tp_repr`.
|
||||||
|
|
||||||
.. c:type:: int (*printfunc)(PyObject *, FILE *, int)
|
|
||||||
|
|
||||||
This is hidden if :const:`PY_LIMITED_API` is set.
|
|
||||||
|
|
||||||
.. c:type:: PyObject *(*getattrfunc)(PyObject *self, char *attr)
|
.. c:type:: PyObject *(*getattrfunc)(PyObject *self, char *attr)
|
||||||
|
|
||||||
Return the value of the named attribute for the object.
|
Return the value of the named attribute for the object.
|
||||||
|
@ -2409,7 +2486,7 @@ with a more verbose initializer::
|
||||||
sizeof(MyObject), /* tp_basicsize */
|
sizeof(MyObject), /* tp_basicsize */
|
||||||
0, /* tp_itemsize */
|
0, /* tp_itemsize */
|
||||||
(destructor)myobj_dealloc, /* tp_dealloc */
|
(destructor)myobj_dealloc, /* tp_dealloc */
|
||||||
0, /* tp_print */
|
0, /* tp_vectorcall_offset */
|
||||||
0, /* tp_getattr */
|
0, /* tp_getattr */
|
||||||
0, /* tp_setattr */
|
0, /* tp_setattr */
|
||||||
0, /* tp_as_async */
|
0, /* tp_as_async */
|
||||||
|
|
|
@ -6,7 +6,7 @@ typedef struct _typeobject {
|
||||||
/* Methods to implement standard operations */
|
/* Methods to implement standard operations */
|
||||||
|
|
||||||
destructor tp_dealloc;
|
destructor tp_dealloc;
|
||||||
printfunc tp_print;
|
Py_ssize_t tp_vectorcall_offset;
|
||||||
getattrfunc tp_getattr;
|
getattrfunc tp_getattr;
|
||||||
setattrfunc tp_setattr;
|
setattrfunc tp_setattr;
|
||||||
PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)
|
PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)
|
||||||
|
|
|
@ -238,6 +238,22 @@ See :pep:`587` for a full description.
|
||||||
(Contributed by Victor Stinner in :issue:`36763`.)
|
(Contributed by Victor Stinner in :issue:`36763`.)
|
||||||
|
|
||||||
|
|
||||||
|
Vectorcall: a fast calling protocol for CPython
|
||||||
|
-----------------------------------------------
|
||||||
|
|
||||||
|
The "vectorcall" protocol is added to the Python/C API.
|
||||||
|
It is meant to formalize existing optimizations which were already done
|
||||||
|
for various classes.
|
||||||
|
Any extension type implementing a callable can use this protocol.
|
||||||
|
|
||||||
|
This is currently provisional,
|
||||||
|
the aim is to make it fully public in Python 3.9.
|
||||||
|
|
||||||
|
See :pep:`590` for a full description.
|
||||||
|
|
||||||
|
(Contributed by Jeroen Demeyer and Mark Shannon in :issue:`36974`.)
|
||||||
|
|
||||||
|
|
||||||
Other Language Changes
|
Other Language Changes
|
||||||
======================
|
======================
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue