[Python-Dev] PEP 576/580: on the complexity of function calls

Jeroen Demeyer J.Demeyer at UGent.be
Sun Mar 24 15:05:36 EDT 2019

Now that the discussion on PEP 576/580 has been opened again, let me 
write something about the complexity of function calls (*), which is 
probably the most frequently given reason against PEP 580.

An important fact is the following: *the status-quo is complex*.

Over time, many performance improvements have been made to function 
calls. Each of these was a relatively small incremental change (for 
example, METH_FASTCALL with *args only was added before 
METH_FASTCALL|METH_KEYWORDS with *args and **kwargs). In the end, all 
these small changes add up to quite a bit of complexity. The fact that 
this complexity isn't documented anywhere and that it's distributed over 
several .c files in the CPython sources makes it perhaps not obvious 
that it's there.

Neither PEP 576 nor PEP 580 tries to remove this complexity. Indeed, the 
complexity is there for good reasons, as it improves performance of 
function calls in many ways. But the PEPs handle it in very different ways.

On the one hand, PEP 580 concentrates all the complexity in the 
protocol. So the protocol looks complex, even though most of it is 
really just formulating existing complexity. More importantly, since the 
complexity is moved to the protocol, it becomes quite easy to use PEP 
580 in a class: you don't need to understand the implementation of PEP 
580 for that.

On the other hand, PEP 576 keeps the existing complexity out of the 
protocol. This means that the implementations of classes using PEP 576 
become more complex, as the existing complexity needs to be implemented 
somewhere. In fact, with PEP 576 the existing complexity needs to be 
implemented in many places, leading for example to code duplication 
between builtin_function_or_method and method_descriptor. This kind of 
code duplication would again occur for third-party method-like classes.

Note that everything I said above about PEP 576 also applies to the 

Best wishes,

(*) With "function calls", I mean most importantly calls of instances of 
builtin_function_or_method, method, method_descriptor and function. But 
since PEP 576/580 are meant for third-party function/method classes, 
also those should be considered.

More information about the Python-Dev mailing list