[Python-ideas] Preserving **kwargs order

Andrew Barnert abarnert at yahoo.com
Thu Mar 20 07:43:21 CET 2014


From: MRAB <python at mrabarnett.plus.com>

Sent: Wednesday, March 19, 2014 7:42 PM


> On 2014-03-20 01:58, Andrew Barnert wrote:
>> On Mar 19, 2014, at 16:32, 
>> Eric Snow <ericsnowcurrently at gmail.com> wrote:
>>>  Hopefully I'll have time to write a proto-PEP on this in the next
>>>  couple weeks, but the gist is that I see 2 options:
>> 
>>  But it doesn't solve the main problem. Right now, you can forward
>>  any arguments perfectly by doing this:
>> 
>>       def wrapper(*args, **kwargs):
>>           return wrappee(*args, **kwargs)
>> 
>>  Your option 2 would require much more verbose code to forward
>>  perfectly.
>> … it would still break the thousands of wrapper functions out

>>  there written with **kwargs.
> 
> Wouldn't it be a problem only if the dict were unpacked and then
> repacked? In the code above, it's merely passing the input kwargs on to
> 'wrappee'.

No, a **kwargs parameter packs the keyword arguments into a dict, and a **kwargs argument unpacks a dict into the keyword arguments; that's exactly what they do. And dicts have arbitrary order.

Besides, the whole point of option 2 is that kwargs is still just a plain dict, and the order is passed via a magic hidden parameter __kwargs_order__. So, even if you _were_ just passing kwargs on without doing anything to it, that still wouldn't help. As long as wrapper (and every other general-purpose wrapper every written) doesn't do anything with __kwargs_order__, the order is not going to get passed to wrapped.

The obvious way to fix this is to make a **kwargs parameter pack the keyword arguments into an OrderedDict, but Guido has already rejected that, which is why Eric Snow had to come up with his two other options. But they don't solve the problem.


More information about the Python-ideas mailing list