[Python-ideas] loosening the restriction on what types may be unpacked using the ** syntax
Andrew Barnert
abarnert at yahoo.com
Thu Apr 3 11:43:30 CEST 2014
Sorry, Yahoo interpreted some key combination as "Send". I think it's mostly readable as-is, but let me clarify a few things.
First, if you're proposing what I think you are, I like the idea. I don't know how useful it would be, but I don't see any real downside. So, +0.5.
And now, comments inline:
From: Andrew Barnert <abarnert at yahoo.com>
> From: Eric Snow <ericsnowcurrently at gmail.com>
> Sent: Wednesday, April 2, 2014 11:54 PM
>
>> T he ** keyword arg unpacking syntax in function calls is useful.
>> However, currently there is an explicit check for a mapping type
>> (presumably PyMapping_Check).
>
> Actually, I believe there's not really an explicit check. In CPython,
> ext_do_call (hg.python.org/cpython/file/default/Python/ceval.c#l4463) uses
> PyDict_Update (https://docs.python.org/3/c-api/dict.html#c.PyDict_Update) to
> copy the kwargs argument to its empty dict, and PyDict_Update, unlike the Python
> equivalent dict.update, "doesn’t fall back to the iterating over a sequence
> of key value pairs if the second argument has no “keys” attribute." In
> PyPy, the relevant code (in Arguments._combine_starstarargs_wrapped,
> https://bitbucket.org/pypy/pypy/src/default/pypy/interpreter/argument.py#cl-95)
> is different, but has the same effect (view_as_kwargs only works on mappings). I
> don't know about other implementations.
However, the language reference does make this an explicit requirement. Section 6.3.4 (https://docs.python.org/3.4/reference/expressions.html#calls) says this:
> If the syntax **expression appears in the function call, expression must evaluate to a mapping, the contents of which are treated as additional keyword arguments. In the case of a keyword appearing in both expression and as an explicit keyword argument, a TypeError exception is raised.
So basically, you just want to change that paragraph.
[snip]
… to:
> If the syntax **expression appears in the function call, expression must
> evaluate to an iterable. If the iterable is a mapping, its contents are treated
> as additional keyword
> arguments. Otherwise, each item in the iterable must itself be an iterator with
> exactly two objects. The first object of each item is treated as an additional
> keyword, and the second as that keyword's argument. In the case of a keyword
> appearing in both expressionand as an
> explicit keyword argument, a TypeErrorexception is raised.
> As for implementation, that's also trivial. In CPython, just change
> ext_do_call to try falling back to PyDict_MergeFromSeq2 if PyDict_Update returns
> a TypeError. In PyPy, just change view_as_kwargs to work on iterables of
> iterable pairs. And so on.
More information about the Python-ideas
mailing list