[Python-Dev] PEP 579 and PEP 580: refactoring C functions and methods
encukou at gmail.com
Wed Sep 12 20:26:47 EDT 2018
On 06/20/18 01:53, Jeroen Demeyer wrote:
> Let me present PEP 579 and PEP 580.
> PEP 579 is an informational meta-PEP, listing some of the issues with
> functions/methods implemented in C. The idea is to create several PEPs
> each fix some part of the issues mentioned in PEP 579.
> PEP 580 is a standards track PEP to introduce a new "C call" protocol,
> which is an important part of PEP 579. In the reference implementation
> (which is work in progress), this protocol will be used by built-in
> functions and methods. However, it should be used by more classes in the
> You find the texts at
I finally had time to read the PEPs carefully.
Overall, great work! PEP 580 does look complicated, but it's well
thought out and addresses real problems.
I think the main advantage over the competing PEP 576 is that it's a
better foundation for solving Cython (and other C-API users) and my PEP
573 (module state access from methods).
With that, I do have some comments.
The reference to PEP 573 is premature. If PEP 580 is implemented then
PEP 573 will build on top, and I don't plan to update PEP 573 before
that. So, I think 580 should be independent. If you agree I can
summarize rationale for "parent", as much as it concerns 580.
# Using tp_print
The tp_print gimmick is my biggest worry.
AFAIK there's no guarantee that a function pointer and Py_ssize_t are
the same size. That makes the backwards-compatibility typedef in the
implementation is quite worrying:
typedef Py_ssize_t printfunc
I can see the benefit for backporting to earlier Python versions, and
maybe that outweighs worries about exotic architectures, but the PEP
should at least have more words on why this is not a problem.
# The C Call protocol
I really like the fact that, in the reference implementation, the flags
are arranged in a way that allows a switch statement to select what to
call. That should be noted, if only to explain why there's no guarantee
of compatibility between Python versions.
# Descriptor behavior
I'd say "SHOULD" rather than "MUST" here. The section describes how to
implement expected/reasonable behavior, but I see no need to limit that.
"if func supports the C call protocol, then func.__set__ must not be
implemented." -- also, __delete__ should not be implemented, right?.
# Generic API functions
I'm a bit worried about PyCCall_FASTCALL's "kwds" argument accepting a
dict, which is mutable. I wouldn't mind dropping that capability, but if
it stays, we need to require that the callable promises to not modify it.
PyCCall_FASTCALL is not a macro, shouldn't it be named PyCCall_FastCall?
# C API functions
The function PyCFunction_GetFlags is, for better or worse, part of the
stable ABI. We shouldn't just give up on it. I'm fine with documenting
that it shouldn't be used, but for functions defined using
PyCFunction_New etc. it should continue behaving as before.
One solution could be to preserve the "definition time" METH_* flags in
the 0xFFF bits of cc_flags and use the other bits for CCALL_*.
# Stable ABI
The section should repeat that PyCFunction_ClsNew is added to the stable
ABI (but nothing else).
More information about the Python-Dev