Call Protocol¶
CPython supports two different calling protocols:tp_call and vectorcall.
Thetp_call Protocol¶
Instances of classes that settp_call
are callable.The signature of the slot is:
PyObject*tp_call(PyObject*callable,PyObject*args,PyObject*kwargs);
A call is made using a tuple for the positional argumentsand a dict for the keyword arguments, similarly tocallable(*args,**kwargs)
in Python code.args must be non-NULL (use an empty tuple if there are no arguments)butkwargs may beNULL if there are no keyword arguments.
This convention is not only used bytp_call:tp_new
andtp_init
also pass arguments this way.
To call an object, usePyObject_Call()
or anothercall API.
The Vectorcall Protocol¶
Added in version 3.9.
The vectorcall protocol was introduced inPEP 590 as an additional protocolfor making calls more efficient.
As rule of thumb, CPython will prefer the vectorcall for internal callsif the callable supports it. However, this is not a hard rule.Additionally, some third-party extensions usetp_call directly(rather than usingPyObject_Call()
).Therefore, a class supporting vectorcall must also implementtp_call
.Moreover, the callable must behave the sameregardless of which protocol is used.The recommended way to achieve this is by settingtp_call
toPyVectorcall_Call()
.This bears repeating:
Warning
A class supporting vectorcallmust also implementtp_call
with the same semantics.
Changed in version 3.12:ThePy_TPFLAGS_HAVE_VECTORCALL
flag is now removed from a classwhen the class’s__call__()
method is reassigned.(This internally setstp_call
only, and thusmay make it behave differently than the vectorcall function.)In earlier Python versions, vectorcall should only be used withimmutable
or static types.
A class should not implement vectorcall if that would be slowerthantp_call. For example, if the callee needs to convertthe arguments to an args tuple and kwargs dict anyway, then there is no pointin implementing vectorcall.
Classes can implement the vectorcall protocol by enabling thePy_TPFLAGS_HAVE_VECTORCALL
flag and settingtp_vectorcall_offset
to the offset inside theobject structure where avectorcallfunc appears.This is a pointer to a function with the following signature:
- typedefPyObject*(*vectorcallfunc)(PyObject*callable,PyObject*const*args,size_tnargsf,PyObject*kwnames)¶
- Part of theStable ABI since version 3.12.
callable is the object being called.
- args is a C array consisting of the positional arguments followed by the
values of the keyword arguments.This can beNULL if there are no arguments.
- nargsf is the number of positional arguments plus possibly the
PY_VECTORCALL_ARGUMENTS_OFFSET
flag.To get the actual number of positional arguments fromnargsf,usePyVectorcall_NARGS()
.
- kwnames is a tuple containing the names of the keyword arguments;
in other words, the keys of the kwargs dict.These names must be strings (instances of
str
or a subclass)and they must be unique.If there are no keyword arguments, thenkwnames can instead beNULL.
- PY_VECTORCALL_ARGUMENTS_OFFSET¶
- Part of theStable ABI since version 3.12.
If this flag is set in a vectorcallnargsf argument, the callee is allowedto temporarily change
args[-1]
. In other words,args points toargument 1 (not 0) in the allocated vector.The callee must restore the value ofargs[-1]
before returning.For
PyObject_VectorcallMethod()
, this flag means instead thatargs[0]
may be changed.Whenever they can do so cheaply (without additional allocation), callersare encouraged to use
PY_VECTORCALL_ARGUMENTS_OFFSET
.Doing so will allow callables such as bound methods to make their onwardcalls (which include a prependedself argument) very efficiently.Added in version 3.8.
To call an object that implements vectorcall, use acall APIfunction as with any other callable.PyObject_Vectorcall()
will usually be most efficient.
Recursion Control¶
When usingtp_call, callees do not need to worry aboutrecursion: CPython usesPy_EnterRecursiveCall()
andPy_LeaveRecursiveCall()
for calls made usingtp_call.
For efficiency, this is not the case for calls done using vectorcall:the callee should usePy_EnterRecursiveCall andPy_LeaveRecursiveCallif needed.
Vectorcall Support API¶
- Py_ssize_tPyVectorcall_NARGS(size_tnargsf)¶
- Part of theStable ABI since version 3.12.
Given a vectorcallnargsf argument, return the actual number ofarguments.Currently equivalent to:
(Py_ssize_t)(nargsf&~PY_VECTORCALL_ARGUMENTS_OFFSET)
However, the function
PyVectorcall_NARGS
should be used to allowfor future extensions.Added in version 3.8.
- vectorcallfuncPyVectorcall_Function(PyObject*op)¶
Ifop does not support the vectorcall protocol (either because the typedoes not or because the specific instance does not), returnNULL.Otherwise, return the vectorcall function pointer stored inop.This function never raises an exception.
This is mostly useful to check whether or notop supports vectorcall,which can be done by checking
PyVectorcall_Function(op)!=NULL
.Added in version 3.9.
- PyObject*PyVectorcall_Call(PyObject*callable,PyObject*tuple,PyObject*dict)¶
- Part of theStable ABI since version 3.12.
Callcallable’s
vectorcallfunc
with positional and keywordarguments given in a tuple and dict, respectively.This is a specialized function, intended to be put in the
tp_call
slot or be used in an implementation oftp_call
.It does not check thePy_TPFLAGS_HAVE_VECTORCALL
flagand it does not fall back totp_call
.Added in version 3.8.
Object Calling API¶
Various functions are available for calling a Python object.Each converts its arguments to a convention supported by the called object –eithertp_call or vectorcall.In order to do as little conversion as possible, pick one that best fitsthe format of data you have available.
The following table summarizes the available functions;please see individual documentation for details.
Function | callable | args | kwargs |
---|---|---|---|
| tuple | dict/ | |
| — | — | |
| 1 object | — | |
| tuple/ | — | |
| format | — | |
obj + | format | — | |
| variadic | — | |
obj + name | variadic | — | |
obj + name | — | — | |
obj + name | 1 object | — | |
| vectorcall | vectorcall | |
| vectorcall | dict/ | |
arg + name | vectorcall | vectorcall |
- PyObject*PyObject_Call(PyObject*callable,PyObject*args,PyObject*kwargs)¶
- Return value: New reference. Part of theStable ABI.
Call a callable Python objectcallable, with arguments given by thetupleargs, and named arguments given by the dictionarykwargs.
args must not beNULL; use an empty tuple if no arguments are needed.If no named arguments are needed,kwargs can beNULL.
Return the result of the call on success, or raise an exception and returnNULL on failure.
This is the equivalent of the Python expression:
callable(*args,**kwargs)
.
- PyObject*PyObject_CallNoArgs(PyObject*callable)¶
- Return value: New reference. Part of theStable ABI since version 3.10.
Call a callable Python objectcallable without any arguments. It is themost efficient way to call a callable Python object without any argument.
Return the result of the call on success, or raise an exception and returnNULL on failure.
Added in version 3.9.
- PyObject*PyObject_CallOneArg(PyObject*callable,PyObject*arg)¶
- Return value: New reference.
Call a callable Python objectcallable with exactly 1 positional argumentarg and no keyword arguments.
Return the result of the call on success, or raise an exception and returnNULL on failure.
Added in version 3.9.
- PyObject*PyObject_CallObject(PyObject*callable,PyObject*args)¶
- Return value: New reference. Part of theStable ABI.
Call a callable Python objectcallable, with arguments given by thetupleargs. If no arguments are needed, thenargs can beNULL.
Return the result of the call on success, or raise an exception and returnNULL on failure.
This is the equivalent of the Python expression:
callable(*args)
.
- PyObject*PyObject_CallFunction(PyObject*callable,constchar*format,...)¶
- Return value: New reference. Part of theStable ABI.
Call a callable Python objectcallable, with a variable number of C arguments.The C arguments are described using a
Py_BuildValue()
style formatstring. The format can beNULL, indicating that no arguments are provided.Return the result of the call on success, or raise an exception and returnNULL on failure.
This is the equivalent of the Python expression:
callable(*args)
.Note that if you only passPyObject* args,
PyObject_CallFunctionObjArgs()
is a faster alternative.Changed in version 3.4:The type offormat was changed from
char*
.
- PyObject*PyObject_CallMethod(PyObject*obj,constchar*name,constchar*format,...)¶
- Return value: New reference. Part of theStable ABI.
Call the method namedname of objectobj with a variable number of Carguments. The C arguments are described by a
Py_BuildValue()
formatstring that should produce a tuple.The format can beNULL, indicating that no arguments are provided.
Return the result of the call on success, or raise an exception and returnNULL on failure.
This is the equivalent of the Python expression:
obj.name(arg1,arg2,...)
.Note that if you only passPyObject* args,
PyObject_CallMethodObjArgs()
is a faster alternative.Changed in version 3.4:The types ofname andformat were changed from
char*
.
- PyObject*PyObject_CallFunctionObjArgs(PyObject*callable,...)¶
- Return value: New reference. Part of theStable ABI.
Call a callable Python objectcallable, with a variable number ofPyObject* arguments. The arguments are provided as a variable numberof parameters followed byNULL.
Return the result of the call on success, or raise an exception and returnNULL on failure.
This is the equivalent of the Python expression:
callable(arg1,arg2,...)
.
- PyObject*PyObject_CallMethodObjArgs(PyObject*obj,PyObject*name,...)¶
- Return value: New reference. Part of theStable ABI.
Call a method of the Python objectobj, where the name of the method is given as aPython string object inname. It is called with a variable number ofPyObject* arguments. The arguments are provided as a variable numberof parameters followed byNULL.
Return the result of the call on success, or raise an exception and returnNULL on failure.
- PyObject*PyObject_CallMethodNoArgs(PyObject*obj,PyObject*name)¶
Call a method of the Python objectobj without arguments,where the name of the method is given as a Python string object inname.
Return the result of the call on success, or raise an exception and returnNULL on failure.
Added in version 3.9.
- PyObject*PyObject_CallMethodOneArg(PyObject*obj,PyObject*name,PyObject*arg)¶
Call a method of the Python objectobj with a single positional argumentarg, where the name of the method is given as a Python string object inname.
Return the result of the call on success, or raise an exception and returnNULL on failure.
Added in version 3.9.
- PyObject*PyObject_Vectorcall(PyObject*callable,PyObject*const*args,size_tnargsf,PyObject*kwnames)¶
- Part of theStable ABI since version 3.12.
Call a callable Python objectcallable.The arguments are the same as for
vectorcallfunc
.Ifcallable supportsvectorcall, this directly callsthe vectorcall function stored incallable.Return the result of the call on success, or raise an exception and returnNULL on failure.
Added in version 3.9.
- PyObject*PyObject_VectorcallDict(PyObject*callable,PyObject*const*args,size_tnargsf,PyObject*kwdict)¶
Callcallable with positional arguments passed exactly as in thevectorcall protocol,but with keyword arguments passed as a dictionarykwdict.Theargs array contains only the positional arguments.
Regardless of which protocol is used internally,a conversion of arguments needs to be done.Therefore, this function should only be used if the calleralready has a dictionary ready to use for the keyword arguments,but not a tuple for the positional arguments.
Added in version 3.9.
- PyObject*PyObject_VectorcallMethod(PyObject*name,PyObject*const*args,size_tnargsf,PyObject*kwnames)¶
- Part of theStable ABI since version 3.12.
Call a method using the vectorcall calling convention. The name of the methodis given as a Python stringname. The object whose method is called isargs[0], and theargs array starting atargs[1] represents the argumentsof the call. There must be at least one positional argument.nargsf is the number of positional arguments includingargs[0],plus
PY_VECTORCALL_ARGUMENTS_OFFSET
if the value ofargs[0]
maytemporarily be changed. Keyword arguments can be passed just like inPyObject_Vectorcall()
.If the object has the
Py_TPFLAGS_METHOD_DESCRIPTOR
feature,this will call the unbound method object with the fullargs vector as arguments.Return the result of the call on success, or raise an exception and returnNULL on failure.
Added in version 3.9.
Call Support API¶
- intPyCallable_Check(PyObject*o)¶
- Part of theStable ABI.
Determine if the objecto is callable. Return
1
if the object is callableand0
otherwise. This function always succeeds.