[Python-Dev] Very Strange Argument Handling Behavior

Guido van Rossum guido at python.org
Sat Apr 17 17:22:19 CEST 2010


On Fri, Apr 16, 2010 at 4:38 PM, Steve Holden <steve at holdenweb.com> wrote:
> I'm sure we wouldn't want to go so far as to inhibit this. (Py 3.1)
>
>>>> def f(**kwargs):
> ...   kwargs[1] = "dummy"
> ...   print(kwargs)
> ...
>>>> f(this="Guido", that="Raymond", the_other="Steve")
> {'this': 'Guido', 1: 'dummy', 'the_other': 'Steve', 'that': 'Raymond'}
>>>>
>
> Or would we? If it's OK to mutate kwargs inside the function to contain
> a non-string key, why isn't it OK to pass a non-string key in?

Because Python promises that the object the callee sees as 'kwargs' is
"just a dict". But the requirement for what the caller passes in is
different: it must pass in a dict whose keys represent argument names.

If you want an API where you can pass in an arbitrary dict to be
received unchanged, don't use **kw. Remember that the caller can
independently decide whether or not to use the **kw notation -- there
is no implied correspondence between the caller's use of **kw and the
callee's use of it. Note this example:

def f(a, b, **k):
  print(a, b, k)

d = {'a': 1, 'b': 2, 'c': 3}
f(**d)

This will print

1 2 {'c': 3}

Note that the k received by f is not the same as the d passed in! (And
yet d of course is not modified by the operation.)

> I understand that it couldn't be generated using keyword argument
> syntax, but I don't see why we discriminate against f(**dict(...)) to
> limit it to what could be generated using keyword argument syntax. Is
> this such a big deal?

Is portability of code to Jython, IronPython, PyPy a big deal?
According to a slide you recently posted to the PSF board list, it is.

-- 
--Guido van Rossum (python.org/~guido)


More information about the Python-Dev mailing list