Python keyword args can be any string

Ben Finney ben+python at
Thu Feb 18 19:58:41 EST 2016

Steven D'Aprano <steve at> writes:

> A work colleague wanted to pass an argument starting with "-" to a
> function.
> Apparently he didn't have a specific argument in mind. He just wanted
> to test the function to breaking point by passing invalid argument
> names.

That seems a reasonable test.

    >>> kwargs = {
    ...         'spam': 13,
    ...         'eggs': 17,
    ...         '-beans': 11,
    ...         }
    >>> foo(**kwargs)    # Should this fail?

It exposes a design smell; by capturing ‘**kwargs’, a function has
deiberately not specified which keyword arguments it will accept.

    >>> def foo_captures_kwargs(*args, **kwargs):
    ...     for (name, value) in kwargs.items():
    ...         print("Got argument {name}={value!r}".format(
    ...                 name=name, value=value))
    >>> foo_captures_kwargs(**kwargs)
    Got argument eggs=17
    Got argument spam=13
    Got argument -beans=11

Still not a bug in Python IMO. It may be a bug in the program; the
design of the function doesn't provide any way to know.

Perhaps the design can be improved by not using ‘**kwargs’ at all, and
instead using a specific set of keyword-only arguments.

    >>> def foo_names_every_argument(*, spam="Lorem", eggs="ipsum"):
    ...     print("Got argument {name}={value!r}".format(
    ...             name='spam', value=spam))
    ...     print("Got argument {name}={value!r}".format(
    ...             name='eggs', value=eggs))
    >>> foo_names_every_argument(**kwargs)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: foo_names_every_argument() got an unexpected keyword argument '-beans'

This is IMO another good reason to migrate ASAP to Python 3; better
design is easier that before.

 \          “Judge: A law student who marks his own papers.” —Henry L. |
  `\                                                           Mencken |
_o__)                                                                  |
Ben Finney

More information about the Python-list mailing list