[Python-Dev] On the METH_FASTCALL calling convention (original) (raw)
Jeroen Demeyer J.Demeyer at UGent.be
Thu Jul 5 10:53:05 EDT 2018
- Previous message (by thread): [Python-Dev] PEP 572: intended scope of assignment expression
- Next message (by thread): [Python-Dev] On the METH_FASTCALL calling convention
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hello all,
As discussed in some other threads ([1], [2]), we should discuss the METH_FASTCALL calling convention.
For passing only positional arguments, a C array of Python objects is used, which is as fast as it can get. When the Python interpreter calls a function, it builds that C array on the interpreter stack:
from dis import dis def f(x, y): return g(x, y, 12) dis(f) 1 0 LOAD_GLOBAL 0 (g) 2 LOAD_FAST 0 (x) 4 LOAD_FAST 1 (y) 6 LOAD_CONST 1 (12) 8 CALL_FUNCTION 3 10 RETURN_VALUE
A C array can also easily and efficiently be handled by the C function receiving it. So I consider this uncontroversial.
The convention for METH_FASTCALL|METH_KEYWORDS is that keyword names are passed as a tuple and keyword values in the same C array with positional arguments. An example:
from dis import dis def f(x, y, z): return f(x, foo=y, bar=z) dis(f) 1 0 LOAD_GLOBAL 0 (f) 2 LOAD_FAST 0 (x) 4 LOAD_FAST 1 (y) 6 LOAD_FAST 2 (z) 8 LOAD_CONST 1 (('foo', 'bar')) 10 CALL_FUNCTION_KW 3 12 RETURN_VALUE
This is pretty clever: it exploits the fact that ('foo', 'bar') is a constant tuple stored in f.code.co_consts. Also, a tuple can be efficiently handled by the called code: it is essentially a thin wrapper around a C array of Python objects. So this works well.
The only case when this handling of keywords is suboptimal is when using **kwargs. In that case, a dict must be converted to a tuple. It looks hard to me to support efficiently both the case of fixed keyword arguments (f(foo=x)) and a keyword dict (f(**kwargs)). Since the former is more common than the latter, the current choice is optimal.
In other words: I see nothing to improve in the calling convention of METH_FASTCALL. I suggest to keep it and make it public as-is.
Jeroen.
[1] https://mail.python.org/pipermail/python-dev/2018-June/153945.html [2] https://mail.python.org/pipermail/python-dev/2018-July/154251.html
- Previous message (by thread): [Python-Dev] PEP 572: intended scope of assignment expression
- Next message (by thread): [Python-Dev] On the METH_FASTCALL calling convention
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]