-
-
Notifications
You must be signed in to change notification settings - Fork 31.8k
C API: What's the status of the half-private FASTCALL calling convention? #106023
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Does vectorcall replace this completely? If that's the case, let's first remove all uses from CPython, and then decide. If not, then it's probably genuinely useful for Cython or others. Let's move it to unstable API in that case. (Or even public?)
|
Replace _PyObject_FastCall() calls with PyObject_Vectorcall().
Replace _PyObject_FastCall() calls with PyObject_Vectorcall().
Replace _PyObject_FastCall() calls with PyObject_Vectorcall().
Remove _PY_FASTCALL_SMALL_STACK constant from the C API: move it to the internal C API (pycore_call.h).
PR #106257 removes
PR #106258 removes the constant from the public C API. |
Replace _PyObject_FastCall() calls with PyObject_Vectorcall().
Remove _PY_FASTCALL_SMALL_STACK constant from the C API: move it to the internal C API (pycore_call.h).
In 2019, a commit implementing PEP 590 removed _PyObject_FastCallKeywords(). My recent commit 00e75a3 removed _PyObject_FastCallDict(). Oh, I didn't notice that I was removing a C function of the FastCall family. I planned to handle these differently. |
On PyPI top 5,000 projects, 10 projects use it. 3 of them are related to pydevd or copies of pydevd. Usage:
|
PyObject_Vectorcall() is available since Python 3.8 and PyObject_VectorcallDict() is available since Python 3.9. _PyObject_FastCall() and _PyObject_FastCallDict() are private functions. IMO it's ok to remove them. The METH_FASTCALL calling convention remains useful and I don't see a need to remove. |
Rename _PyObject_FastCallDictTstate() to _PyObject_VectorcallDictTstate().
I wrote PR #106265 to remove the private _PyObject_FastCall() function. |
When removing them, it would be nice to add them to What's New, mentioning that they were private but documenting what to call instead. |
Rename _PyObject_FastCallDictTstate() to _PyObject_VectorcallDictTstate().
I removed the FastCall C API and explained how to migrate in What's New in Python 3.13. I removed _PyObject_FastCall(), _PyObject_FastCallDict(), _PY_FASTCALL_SMALL_STACK and _PyStack_AsDict() from the public C API. I removed _PyObject_FastCallTstate() and _PyObject_FastCallDictTstate() of the internal C API. The METH_FASTCALL constant stays for now. |
The function _PyObject_FastCall() was restored.
…l() (python#117633)" This reverts commit 9a12f5d. I was wrong: the _PyObject_FastCall() function was removed. But we kept the _PyObject_FastCallDict() function.
…hon#117633) The function _PyObject_FastCall() was restored.
…l() (python#117633)" (python#117676) This reverts commit 9a12f5d. I was wrong: the _PyObject_FastCall() function was removed. But we kept the _PyObject_FastCallDict() function.
`_PyObject_FastCall` will be removed in 3.13. It can safely replaced by `PyObject_Vectorcall` (available since `3.9`) / `_PyObject_Vectorcall` (available since `3.8`). python/cpython#106023 (comment) https://peps.python.org/pep-0590/ Fixes ```cpp /home/runner/work/mypy/mypy/mypyc/lib-rt/pythonsupport.h: In function ‘update_bases’: (diff) /home/runner/work/mypy/mypy/mypyc/lib-rt/pythonsupport.h:62:20: error: implicit declaration of function ‘_PyObject_FastCall’; did you mean ‘PyObject_Call’? [-Werror=implicit-function-declaration] (diff) 62 | new_base = _PyObject_FastCall(meth, stack, 1); (diff) /home/runner/work/mypy/mypy/mypyc/lib-rt/pythonsupport.h:62:18: error: assignment to ‘PyObject *’ {aka ‘struct _object *’} from ‘int’ makes pointer from integer without a cast [-Werror=int-conversion] (diff) 62 | new_base = _PyObject_FastCall(meth, stack, 1); (diff) | ^ (diff) /home/runner/work/mypy/mypy/mypyc/lib-rt/pythonsupport.h: In function ‘init_subclass’: (diff) /home/runner/work/mypy/mypy/mypyc/lib-rt/pythonsupport.h:111:11: error: assignment to ‘PyObject *’ {aka ‘struct _object *’} from ‘int’ makes pointer from integer without a cast [-Werror=int-conversion] (diff) 111 | super = _PyObject_FastCall((PyObject *)&PySuper_Type, args, 2); (diff) | ^ (diff) ```
Hi,
In 2017, I added a new experimental FASTCALL calling convention. See my articles about it: The start of the FASTCALL project and FASTCALL microbenchmarks. It avoids the need to create a temporary tuple to pass positional arguments and the need to create a temporary dictionary to pass keyword arguments. I did my best to keep this API private. I added functions prefixed with
_Py
:_PyObject_Fastcall()
. Cython is eager to always use the fastest code and quickly adopted this newMETH_FASTCALL
calling convention... oops, I forgot to add a_Py
prefix since theseMETH
constants don't start withPy
.In 2019, this calling convention was extended to support also method calls (pass the
self
argument): PEP 590 – Vectorcall: a fast calling protocol for CPython. This new API is public and standardized. For example, it added publicPyVectorcall_Function()
andPyObject_Vectorcall()
functions.In 2023, the FASTCALL API is still around in the public C API:
Can it be deprecated? Removed? I suppose that if we are in the unknown, the safe option is to start by deprecating it in Python 3.13 and plan its removal in Python 3.15.
cc @encukou
Victor
Linked PRs
The text was updated successfully, but these errors were encountered: