Josh Rosenberg <shadowranger+pyt...@gmail.com> added the comment:

Even if making a copy is necessary when the underlying function receives the 
dict "raw", preemptively performing the copy (before knowing if the function 
being called is a Vectorcall function) means that when it's a Vectorcall 
function (e.g. all user-defined functions, right?), instead of just copying 
from the original dict to the unpacked stack for vectorcall, it makes an 
intermediate copy, then copies from that copy to the unpacked stack later on; 
the copy is otherwise completely unused.

The extra bytecode isn't even defending against "dict-like" kwargs, because 
CALL_FUNCTION_EX itself already copies to a true dict for anything that's not 
an exact dict (that defense shouldn't even be there if the bytecode compiler is 
already guaranteeing a true dict).

Seems like, if preventing the caller's dict from being passed directly to the 
underlying function is necessary and intended, it should be done in 
PyObject_Call (which can avoid the copy entirely when call a Vectorcall 
function and when the reference count on the dict is 1), not at the bytecode 
interpreter layer. As is, PyObject_Call is already violating the documented 
behavior by *not* matching the behavior of callable(*args, **kwargs) (see 
#42629), so moving it to PyObject_Call would fix that problem and improve 
performance passing a single kwargs.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue42033>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to