[Python-Dev] PEP 575 (Unifying function/method classes) update (original) (raw)
Stefan Behnel stefan_ml at behnel.de
Mon Jun 18 13:49:28 EDT 2018
- Previous message (by thread): [Python-Dev] PEP 575 (Unifying function/method classes) update
- Next message (by thread): [Python-Dev] PEP 575 (Unifying function/method classes) update
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Victor Stinner schrieb am 18.06.2018 um 15:09:
I tried two options to add support for FASTCALL on calling an object: add a flag in tpflags and reuse tpcall, or add a new tpfastcall slot. I failed to implement correctly any of these two options.
There are multiple issues with tpfastcall: * ABI issue: it's possible to load a C extension using the old ABI, without tpfastcall: it's not possible to write type->tpfastcall on such type. This limitation causes different issues.
Not a problem if we rededicate the unused (since Py3.0) "tp_print" slot for it.
Even better, since the slot exists already in Py3.0+, tools like Cython, NumPy (with its ufuncs etc.) or generic function dispatchers, basically anything that benefits from fast calls, can enable support for it in all CPython 3.x versions and benefit from faster calls among each other, independent of the support in CPython. The explicit type flag opt-in that the PEP proposes makes this completely safe.
* If tpcall is modified, tpfastcall may be outdated. Same if tpfastcall is modified.
Slots are fixed at type creation and should never be modified afterwards.
What happens on "del obj.call" or "del type.call"?
$ python3.7 -c 'del len.call' Traceback (most recent call last): File "", line 1, in AttributeError: 'builtin_function_or_method' object attribute 'call' is read-only
$ python3.7 -c 'del type.call' Traceback (most recent call last): File "", line 1, in TypeError: can't set attributes of built-in/extension type 'type'
And a really lovely one:
$ python3.7 -c 'del (lambda:0).call' Traceback (most recent call last): File "", line 1, in AttributeError: call
* Many public functions of the C API still requires the tuple and dict to pass positional and keyword arguments, so a compatibility layer is required to types who only want to implement FASTCALL.
Well, yes. It would require a trivial piece of code to map between the two. Fine with me.
Related issue: what is something calls tpcall with (args: tuple, kwargs: dict)? Crash or call a compatibility layer converting arguments to FASTCALL calling convention?
The latter, obviously. Also easy to implement, with the usual undefined dict order caveat (although that's probably solved when running in Py3.6+).
I abandoned my idea for two reasons:
1) in the worst case, my changes caused a crash which is not accepted for an optimization.
This isn't really an optimisation. It's a generalisation of the call protocol.
My first intent was to removed the propertydescrget() hack because its implementation is fragile and caused crashes.
Not sure which hack you mean.
2) we implemented a lot of other optimizations which made calls faster without having to touch tpcall nor tpfastcall. The benefit of FASTCALL for tpcall/tpfastcall was not really significant.
What Jeroen said. Cleaning up the implementation and generalising the call protocol is going to open up a wonderfully bright future for CPython. :)
Stefan
- Previous message (by thread): [Python-Dev] PEP 575 (Unifying function/method classes) update
- Next message (by thread): [Python-Dev] PEP 575 (Unifying function/method classes) update
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]