Keyword arguments with non-string names

When passing **kwargs to a callable, the expectation is that kwargs is a dict with string keys. The interpreter enforces that it's a dict, but it does NOT check the types of the keys. It's currently the job of the called function to check that. In some cases, this check is not applied:
from collections import OrderedDict OrderedDict(**{1:2}) OrderedDict([(1, 2)])
So this leads to the question: should the interpreter check the keys of a **kwargs dict? I don't have an answer myself, I'm just asking the question because it comes up in https://github.com/python/cpython/pull/13930 and https://github.com/python/cpython/pull/14589 Jeroen.

On 2019-07-09 14:36, Jeroen Demeyer wrote:
So this leads to the question: should the interpreter check the keys of a **kwargs dict?
Some pointers: - https://bugs.python.org/issue8419 - https://bugs.python.org/issue29360

On 7/9/2019 8:50 AM, Jeroen Demeyer wrote:
On 2019-07-09 14:36, Jeroen Demeyer wrote:
So this leads to the question: should the interpreter check the keys of a **kwargs dict?
Some pointers: - https://bugs.python.org/issue8419 - https://bugs.python.org/issue29360
It was also discussed last October; which I believe is the most recent previous discussion: https://mail.python.org/pipermail/python-dev/2018-October/155435.html Janzert

Thanks for the pointer, but that's more about allowing strings which are not valid identifiers. I'm talking about passing non-strings and more specifically about the C protocol. For Python functions, non-string keyword arguments are already disallowed, but that's because of the implementation of the "function" object, it's not enforced by the CPython core. Jeroen.

Thinking about this, I don't believe allowing non-string keys here are a desirable feature. It's tempting not to check for this in some cases where it does no harm (skipping the check shaves a few microseconds off execution time), but I think the reference manual should require strings here and we would do well to tighten the implementation. We may find though that this has accidentally become a gray area that some code has come to depend on, so we may have to deprecate it. This really depends on how much code depends on it though, there's no strict rule for such cases. On Tue, Jul 9, 2019 at 9:42 AM Jeroen Demeyer <J.Demeyer@ugent.be> wrote:
Thanks for the pointer, but that's more about allowing strings which are not valid identifiers. I'm talking about passing non-strings and more specifically about the C protocol. For Python functions, non-string keyword arguments are already disallowed, but that's because of the implementation of the "function" object, it's not enforced by the CPython core.
Jeroen. _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/JSAQAZD2...
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him/his **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>

I realized something that makes this even more tricky: dicts are mutable. So even if the dict contains only string keys at call time, it could theoretically be changed by the time that keywords are parsed. So for calling conventions passing dicts, I would leave it to the callee to sanity check the dict (this is the status quo). For the vectorcall/FASTCALL calling convention, the situation is a lot better: the call arguments are immutable and there are not many places where vectorcall calls are made with keywords. So we could check it on the caller side. I'll try to implement that. Jeroen.
participants (3)
-
Guido van Rossum
-
Janzert
-
Jeroen Demeyer