Python keyword args can be any string

Chris Angelico rosuav at gmail.com
Thu Feb 18 00:57:23 EST 2016


On Thu, Feb 18, 2016 at 4:42 PM, Steven D'Aprano
<steve+comp.lang.python at pearwood.info> wrote:
> Today I learned that **kwargs style keyword arguments can be any string:
>
>
> py> def test(**kw):
> ...     print(kw)
> ...
> py> kwargs = {'abc-def': 42, '': 23, '---': 999, '123': 17}
> py> test(**kwargs)
> {'': 23, '123': 17, '---': 999, 'abc-def': 42}
>
>
> Bug or feature?

Probably neither. It's something that can't hurt, so there's no point
specifically blocking it. You can do the same thing with other
dictionaries:

>>> globals()["abc-def"] = 42
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__',
'__spec__', 'abc-def']
>>> class Blob: pass
...
>>> b = Blob()
>>> b.__dict__[""] = 23
>>> dir(b)
['', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
'__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__']

I suppose it's possible for this to be a vulnerability, eg if you
build up an XML node using keyword arguments for attributes, and end
up accepting something with a space in it. But most of the time, the
only consequence is that you use a dict to create a situation that can
only be handled with another dict. Doesn't seem worth the hassle of
preventing it, but I would also see this as a bizarre thing to
deliberately exploit.

ChrisA


More information about the Python-list mailing list