bpo-39245: Make Vectorcall C API public (GH-17893)
* Add backcompat defines and move non-limited API declaration to cpython/
This partially reverts commit 2ff58a24e8
which added PyObject_CallNoArgs to the 3.9+ stable ABI. This should not
be done; there are enough other call APIs in the stable ABI to choose from.
* Adjust documentation
Mark all newly public functions as added in 3.9.
Add a note about the 3.8 provisional names.
Add notes on public API.
* Put PyObject_CallNoArgs back in the limited API
* Rename PyObject_FastCallDict to PyObject_VectorcallDict
This commit is contained in:
parent
d2f9667264
commit
3f563cea56
|
@ -35,17 +35,11 @@ To call an object, use :c:func:`PyObject_Call` or other
|
|||
The Vectorcall Protocol
|
||||
-----------------------
|
||||
|
||||
.. versionadded:: 3.8
|
||||
.. versionadded:: 3.9
|
||||
|
||||
The vectorcall protocol was introduced in :pep:`590` as an additional protocol
|
||||
for making calls more efficient.
|
||||
|
||||
.. warning::
|
||||
|
||||
The vectorcall API is provisional and expected to become public in
|
||||
Python 3.9, with a different names and, possibly, changed semantics.
|
||||
If you use the it, plan for updating your code for Python 3.9.
|
||||
|
||||
As rule of thumb, CPython will prefer the vectorcall for internal calls
|
||||
if the callable supports it. However, this is not a hard rule.
|
||||
Additionally, some third-party extensions use *tp_call* directly
|
||||
|
@ -69,7 +63,7 @@ the arguments to an args tuple and kwargs dict anyway, then there is no point
|
|||
in implementing vectorcall.
|
||||
|
||||
Classes can implement the vectorcall protocol by enabling the
|
||||
:const:`_Py_TPFLAGS_HAVE_VECTORCALL` flag and setting
|
||||
:const:`Py_TPFLAGS_HAVE_VECTORCALL` flag and setting
|
||||
:c:member:`~PyTypeObject.tp_vectorcall_offset` to the offset inside the
|
||||
object structure where a *vectorcallfunc* appears.
|
||||
This is a pointer to a function with the following signature:
|
||||
|
@ -97,7 +91,7 @@ This is a pointer to a function with the following signature:
|
|||
argument 1 (not 0) in the allocated vector.
|
||||
The callee must restore the value of ``args[-1]`` before returning.
|
||||
|
||||
For :c:func:`_PyObject_VectorcallMethod`, this flag means instead that
|
||||
For :c:func:`PyObject_VectorcallMethod`, this flag means instead that
|
||||
``args[0]`` may be changed.
|
||||
|
||||
Whenever they can do so cheaply (without additional allocation), callers
|
||||
|
@ -107,7 +101,20 @@ This is a pointer to a function with the following signature:
|
|||
|
||||
To call an object that implements vectorcall, use a :ref:`call API <capi-call>`
|
||||
function as with any other callable.
|
||||
:c:func:`_PyObject_Vectorcall` will usually be most efficient.
|
||||
:c:func:`PyObject_Vectorcall` will usually be most efficient.
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
In CPython 3.8, the vectorcall API and related functions were available
|
||||
provisionally under names with a leading underscore:
|
||||
``_PyObject_Vectorcall``, ``_Py_TPFLAGS_HAVE_VECTORCALL``,
|
||||
``_PyObject_VectorcallMethod``, ``_PyVectorcall_Function``,
|
||||
``_PyObject_CallOneArg``, ``_PyObject_CallMethodNoArgs``,
|
||||
``_PyObject_CallMethodOneArg``.
|
||||
Additionally, ``PyObject_VectorcallDict`` was available as
|
||||
``_PyObject_FastCallDict``.
|
||||
The old names are still defined as aliases of the new, non-underscored names.
|
||||
|
||||
|
||||
Recursion Control
|
||||
|
@ -137,9 +144,11 @@ Vectorcall Support API
|
|||
However, the function ``PyVectorcall_NARGS`` should be used to allow
|
||||
for future extensions.
|
||||
|
||||
This function is not part of the `limited API <stable>`_.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
.. c:function:: vectorcallfunc _PyVectorcall_Function(PyObject *op)
|
||||
.. c:function:: vectorcallfunc PyVectorcall_Function(PyObject *op)
|
||||
|
||||
If *op* does not support the vectorcall protocol (either because the type
|
||||
does not or because the specific instance does not), return *NULL*.
|
||||
|
@ -147,7 +156,9 @@ Vectorcall Support API
|
|||
This function never raises an exception.
|
||||
|
||||
This is mostly useful to check whether or not *op* supports vectorcall,
|
||||
which can be done by checking ``_PyVectorcall_Function(op) != NULL``.
|
||||
which can be done by checking ``PyVectorcall_Function(op) != NULL``.
|
||||
|
||||
This function is not part of the `limited API <stable>`_.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
|
@ -158,9 +169,11 @@ Vectorcall Support API
|
|||
|
||||
This is a specialized function, intended to be put in the
|
||||
:c:member:`~PyTypeObject.tp_call` slot or be used in an implementation of ``tp_call``.
|
||||
It does not check the :const:`_Py_TPFLAGS_HAVE_VECTORCALL` flag
|
||||
It does not check the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag
|
||||
and it does not fall back to ``tp_call``.
|
||||
|
||||
This function is not part of the `limited API <stable>`_.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
|
||||
|
@ -185,7 +198,7 @@ please see individual documentation for details.
|
|||
+------------------------------------------+------------------+--------------------+---------------+
|
||||
| :c:func:`PyObject_CallNoArgs` | ``PyObject *`` | --- | --- |
|
||||
+------------------------------------------+------------------+--------------------+---------------+
|
||||
| :c:func:`_PyObject_CallOneArg` | ``PyObject *`` | 1 object | --- |
|
||||
| :c:func:`PyObject_CallOneArg` | ``PyObject *`` | 1 object | --- |
|
||||
+------------------------------------------+------------------+--------------------+---------------+
|
||||
| :c:func:`PyObject_CallObject` | ``PyObject *`` | tuple/``NULL`` | --- |
|
||||
+------------------------------------------+------------------+--------------------+---------------+
|
||||
|
@ -197,15 +210,15 @@ please see individual documentation for details.
|
|||
+------------------------------------------+------------------+--------------------+---------------+
|
||||
| :c:func:`PyObject_CallMethodObjArgs` | obj + name | variadic | --- |
|
||||
+------------------------------------------+------------------+--------------------+---------------+
|
||||
| :c:func:`_PyObject_CallMethodNoArgs` | obj + name | --- | --- |
|
||||
| :c:func:`PyObject_CallMethodNoArgs` | obj + name | --- | --- |
|
||||
+------------------------------------------+------------------+--------------------+---------------+
|
||||
| :c:func:`_PyObject_CallMethodOneArg` | obj + name | 1 object | --- |
|
||||
| :c:func:`PyObject_CallMethodOneArg` | obj + name | 1 object | --- |
|
||||
+------------------------------------------+------------------+--------------------+---------------+
|
||||
| :c:func:`_PyObject_Vectorcall` | ``PyObject *`` | vectorcall | vectorcall |
|
||||
| :c:func:`PyObject_Vectorcall` | ``PyObject *`` | vectorcall | vectorcall |
|
||||
+------------------------------------------+------------------+--------------------+---------------+
|
||||
| :c:func:`_PyObject_FastCallDict` | ``PyObject *`` | vectorcall | dict/``NULL`` |
|
||||
| :c:func:`PyObject_VectorcallDict` | ``PyObject *`` | vectorcall | dict/``NULL`` |
|
||||
+------------------------------------------+------------------+--------------------+---------------+
|
||||
| :c:func:`_PyObject_VectorcallMethod` | arg + name | vectorcall | vectorcall |
|
||||
| :c:func:`PyObject_VectorcallMethod` | arg + name | vectorcall | vectorcall |
|
||||
+------------------------------------------+------------------+--------------------+---------------+
|
||||
|
||||
|
||||
|
@ -235,7 +248,7 @@ please see individual documentation for details.
|
|||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. c:function:: PyObject* _PyObject_CallOneArg(PyObject *callable, PyObject *arg)
|
||||
.. c:function:: PyObject* PyObject_CallOneArg(PyObject *callable, PyObject *arg)
|
||||
|
||||
Call a callable Python object *callable* with exactly 1 positional argument
|
||||
*arg* and no keyword arguments.
|
||||
|
@ -243,6 +256,8 @@ please see individual documentation for details.
|
|||
Return the result of the call on success, or raise an exception and return
|
||||
*NULL* on failure.
|
||||
|
||||
This function is not part of the `limited API <stable>`_.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
|
@ -320,7 +335,7 @@ please see individual documentation for details.
|
|||
*NULL* on failure.
|
||||
|
||||
|
||||
.. c:function:: PyObject* _PyObject_CallMethodNoArgs(PyObject *obj, PyObject *name)
|
||||
.. c:function:: PyObject* PyObject_CallMethodNoArgs(PyObject *obj, PyObject *name)
|
||||
|
||||
Call a method of the Python object *obj* without arguments,
|
||||
where the name of the method is given as a Python string object in *name*.
|
||||
|
@ -328,10 +343,12 @@ please see individual documentation for details.
|
|||
Return the result of the call on success, or raise an exception and return
|
||||
*NULL* on failure.
|
||||
|
||||
This function is not part of the `limited API <stable>`_.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. c:function:: PyObject* _PyObject_CallMethodOneArg(PyObject *obj, PyObject *name, PyObject *arg)
|
||||
.. c:function:: PyObject* PyObject_CallMethodOneArg(PyObject *obj, PyObject *name, PyObject *arg)
|
||||
|
||||
Call a method of the Python object *obj* with a single positional argument
|
||||
*arg*, where the name of the method is given as a Python string object in
|
||||
|
@ -340,10 +357,12 @@ please see individual documentation for details.
|
|||
Return the result of the call on success, or raise an exception and return
|
||||
*NULL* on failure.
|
||||
|
||||
This function is not part of the `limited API <stable>`_.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. c:function:: PyObject* _PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)
|
||||
.. c:function:: PyObject* PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)
|
||||
|
||||
Call a callable Python object *callable*.
|
||||
The arguments are the same as for :c:type:`vectorcallfunc`.
|
||||
|
@ -353,15 +372,11 @@ please see individual documentation for details.
|
|||
Return the result of the call on success, or raise an exception and return
|
||||
*NULL* on failure.
|
||||
|
||||
.. note::
|
||||
This function is not part of the `limited API <stable>`_.
|
||||
|
||||
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.9
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
.. c:function:: PyObject* _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwdict)
|
||||
.. c:function:: PyObject* PyObject_VectorcallDict(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwdict)
|
||||
|
||||
Call *callable* with positional arguments passed exactly as in the vectorcall_ protocol,
|
||||
but with keyword arguments passed as a dictionary *kwdict*.
|
||||
|
@ -373,15 +388,11 @@ please see individual documentation for details.
|
|||
already has a dictionary ready to use for the keyword arguments,
|
||||
but not a tuple for the positional arguments.
|
||||
|
||||
.. note::
|
||||
This function is not part of the `limited API <stable>`_.
|
||||
|
||||
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.9
|
||||
|
||||
.. versionadded:: 3.8
|
||||
|
||||
.. c:function:: PyObject* _PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames)
|
||||
.. c:function:: PyObject* PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames)
|
||||
|
||||
Call a method using the vectorcall calling convention. The name of the method
|
||||
is given as a Python string *name*. The object whose method is called is
|
||||
|
@ -390,7 +401,7 @@ please see individual documentation for details.
|
|||
*nargsf* is the number of positional arguments including *args[0]*,
|
||||
plus :const:`PY_VECTORCALL_ARGUMENTS_OFFSET` if the value of ``args[0]`` may
|
||||
temporarily be changed. Keyword arguments can be passed just like in
|
||||
:c:func:`_PyObject_Vectorcall`.
|
||||
:c:func:`PyObject_Vectorcall`.
|
||||
|
||||
If the object has the :const:`Py_TPFLAGS_METHOD_DESCRIPTOR` feature,
|
||||
this will call the unbound method object with the full
|
||||
|
@ -399,6 +410,8 @@ please see individual documentation for details.
|
|||
Return the result of the call on success, or raise an exception and return
|
||||
*NULL* on failure.
|
||||
|
||||
This function is not part of the `limited API <stable>`_.
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
|
|
|
@ -684,15 +684,15 @@ and :c:type:`PyType_Type` effectively act as defaults.)
|
|||
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`
|
||||
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 *vectorcallfunc* pointer may be ``NULL``, in which case the instance behaves
|
||||
as if :const:`_Py_TPFLAGS_HAVE_VECTORCALL` was not set: calling the instance
|
||||
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
|
||||
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 :c:func:`PyVectorcall_Call`.
|
||||
|
@ -719,7 +719,7 @@ and :c:type:`PyType_Type` effectively act as defaults.)
|
|||
**Inheritance:**
|
||||
|
||||
This field is always inherited.
|
||||
However, the :const:`_Py_TPFLAGS_HAVE_VECTORCALL` flag is not
|
||||
However, the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is not
|
||||
always inherited. If it's not, then the subclass won't use
|
||||
:ref:`vectorcall <vectorcall>`, except when
|
||||
:c:func:`PyVectorcall_Call` is explicitly called.
|
||||
|
@ -1153,7 +1153,7 @@ and :c:type:`PyType_Type` effectively act as defaults.)
|
|||
type structure.
|
||||
|
||||
|
||||
.. data:: _Py_TPFLAGS_HAVE_VECTORCALL
|
||||
.. data:: Py_TPFLAGS_HAVE_VECTORCALL
|
||||
|
||||
This bit is set when the class implements
|
||||
the :ref:`vectorcall protocol <vectorcall>`.
|
||||
|
@ -1163,15 +1163,9 @@ and :c:type:`PyType_Type` effectively act as defaults.)
|
|||
|
||||
This bit is inherited for *static* subtypes if
|
||||
:c:member:`~PyTypeObject.tp_call` is also inherited.
|
||||
`Heap types`_ do not inherit ``_Py_TPFLAGS_HAVE_VECTORCALL``.
|
||||
`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
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
.. c:member:: const char* PyTypeObject.tp_doc
|
||||
|
|
|
@ -29,7 +29,7 @@ PyAPI_FUNC(PyObject *) _PyStack_AsDict(
|
|||
/* Suggested size (number of positional arguments) for arrays of PyObject*
|
||||
allocated on a C stack to avoid allocating memory on the heap memory. Such
|
||||
array is used to pass positional arguments to call functions of the
|
||||
_PyObject_Vectorcall() family.
|
||||
PyObject_Vectorcall() family.
|
||||
|
||||
The size is chosen to not abuse the C stack and so limit the risk of stack
|
||||
overflow. The size is also chosen to allow using the small stack for most
|
||||
|
@ -45,8 +45,8 @@ PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(
|
|||
|
||||
/* === Vectorcall protocol (PEP 590) ============================= */
|
||||
|
||||
/* Call callable using tp_call. Arguments are like _PyObject_Vectorcall()
|
||||
or _PyObject_FastCallDict() (both forms are supported),
|
||||
/* Call callable using tp_call. Arguments are like PyObject_Vectorcall()
|
||||
or PyObject_FastCallDict() (both forms are supported),
|
||||
except that nargs is plainly the number of arguments without flags. */
|
||||
PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall(
|
||||
PyThreadState *tstate,
|
||||
|
@ -63,7 +63,7 @@ PyVectorcall_NARGS(size_t n)
|
|||
}
|
||||
|
||||
static inline vectorcallfunc
|
||||
_PyVectorcall_Function(PyObject *callable)
|
||||
PyVectorcall_Function(PyObject *callable)
|
||||
{
|
||||
assert(callable != NULL);
|
||||
PyTypeObject *tp = Py_TYPE(callable);
|
||||
|
@ -103,7 +103,7 @@ _PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable,
|
|||
assert(kwnames == NULL || PyTuple_Check(kwnames));
|
||||
assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0);
|
||||
|
||||
vectorcallfunc func = _PyVectorcall_Function(callable);
|
||||
vectorcallfunc func = PyVectorcall_Function(callable);
|
||||
if (func == NULL) {
|
||||
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
|
||||
return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames);
|
||||
|
@ -113,7 +113,7 @@ _PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable,
|
|||
}
|
||||
|
||||
static inline PyObject *
|
||||
_PyObject_Vectorcall(PyObject *callable, PyObject *const *args,
|
||||
PyObject_Vectorcall(PyObject *callable, PyObject *const *args,
|
||||
size_t nargsf, PyObject *kwnames)
|
||||
{
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
|
@ -121,9 +121,18 @@ _PyObject_Vectorcall(PyObject *callable, PyObject *const *args,
|
|||
args, nargsf, kwnames);
|
||||
}
|
||||
|
||||
/* Same as _PyObject_Vectorcall except that keyword arguments are passed as
|
||||
// Backwards compatibility aliases for API that was provisional in Python 3.8
|
||||
#define _PyObject_Vectorcall PyObject_Vectorcall
|
||||
#define _PyObject_VectorcallMethod PyObject_VectorcallMethod
|
||||
#define _PyObject_FastCallDict PyObject_VectorcallDict
|
||||
#define _PyVectorcall_Function PyVectorcall_Function
|
||||
#define _PyObject_CallOneArg PyObject_CallOneArg
|
||||
#define _PyObject_CallMethodNoArgs PyObject_CallMethodNoArgs
|
||||
#define _PyObject_CallMethodOneArg PyObject_CallMethodOneArg
|
||||
|
||||
/* Same as PyObject_Vectorcall except that keyword arguments are passed as
|
||||
dict, which may be NULL if there are no keyword arguments. */
|
||||
PyAPI_FUNC(PyObject *) _PyObject_FastCallDict(
|
||||
PyAPI_FUNC(PyObject *) PyObject_VectorcallDict(
|
||||
PyObject *callable,
|
||||
PyObject *const *args,
|
||||
size_t nargsf,
|
||||
|
@ -133,7 +142,7 @@ PyAPI_FUNC(PyObject *) _PyObject_FastCallDict(
|
|||
"tuple" and keyword arguments "dict". "dict" may also be NULL */
|
||||
PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict);
|
||||
|
||||
/* Same as _PyObject_Vectorcall except without keyword arguments */
|
||||
/* Same as PyObject_Vectorcall except without keyword arguments */
|
||||
static inline PyObject *
|
||||
_PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs)
|
||||
{
|
||||
|
@ -151,7 +160,7 @@ _PyObject_CallNoArg(PyObject *func) {
|
|||
}
|
||||
|
||||
static inline PyObject *
|
||||
_PyObject_CallOneArg(PyObject *func, PyObject *arg)
|
||||
PyObject_CallOneArg(PyObject *func, PyObject *arg)
|
||||
{
|
||||
assert(arg != NULL);
|
||||
PyObject *_args[2];
|
||||
|
@ -162,19 +171,19 @@ _PyObject_CallOneArg(PyObject *func, PyObject *arg)
|
|||
return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL);
|
||||
}
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyObject_VectorcallMethod(
|
||||
PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod(
|
||||
PyObject *name, PyObject *const *args,
|
||||
size_t nargsf, PyObject *kwnames);
|
||||
|
||||
static inline PyObject *
|
||||
_PyObject_CallMethodNoArgs(PyObject *self, PyObject *name)
|
||||
PyObject_CallMethodNoArgs(PyObject *self, PyObject *name)
|
||||
{
|
||||
return _PyObject_VectorcallMethod(name, &self,
|
||||
1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
|
||||
}
|
||||
|
||||
static inline PyObject *
|
||||
_PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg)
|
||||
PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg)
|
||||
{
|
||||
assert(arg != NULL);
|
||||
PyObject *args[2] = {self, arg};
|
||||
|
@ -207,7 +216,7 @@ _PyObject_VectorcallMethodId(
|
|||
if (!oname) {
|
||||
return NULL;
|
||||
}
|
||||
return _PyObject_VectorcallMethod(oname, args, nargsf, kwnames);
|
||||
return PyObject_VectorcallMethod(oname, args, nargsf, kwnames);
|
||||
}
|
||||
|
||||
static inline PyObject *
|
||||
|
|
|
@ -279,7 +279,9 @@ given type object has a specified feature.
|
|||
|
||||
/* Set if the type implements the vectorcall protocol (PEP 590) */
|
||||
#ifndef Py_LIMITED_API
|
||||
#define _Py_TPFLAGS_HAVE_VECTORCALL (1UL << 11)
|
||||
#define Py_TPFLAGS_HAVE_VECTORCALL (1UL << 11)
|
||||
// Backwards compatibility alias for API that was provisional in Python 3.8
|
||||
#define _Py_TPFLAGS_HAVE_VECTORCALL Py_TPFLAGS_HAVE_VECTORCALL
|
||||
#endif
|
||||
|
||||
/* Set if the type is 'ready' -- fully initialized */
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
The Vectorcall API (PEP 590) was made public, adding the functions
|
||||
``PyObject_Vectorcall``, ``PyObject_VectorcallMethod``,
|
||||
``PyVectorcall_Function``, ``PyObject_CallOneArg``,
|
||||
``PyObject_CallMethodNoArgs``, ``PyObject_CallMethodOneArg``,
|
||||
``PyObject_FastCallDict``, and the flag ``Py_TPFLAGS_HAVE_VECTORCALL``.
|
Loading…
Reference in New Issue