My 2 cents: disallowing everything that doesn’t work in the x(dict(foo=bar)) syntax from the x(**{'foo': bar}) syntax would break a lot of code I have in production
@Gouvernathor This is a totally pointless discussion, for two reasons:
If you’re using **kwargs in your function signature, you don’t have any way of accessing its contents except via a dictionary. So having non-identifier keys is an absolute non-issue.
If you’re really bothered by this behaviour, there is a very simple check you can add to your function, and it can easily be implemented as a decorator:
def foo(**kwargs):
if not all(map(str.isidentifier, kwargs)):
raise ValueError("keywords must be identifiers")
print(kwargs)
Yes you have, for example passing **kwargs to another function not having a **dict in its signature, and returning the result. Also, your argument would also work to include non-string keys in the kwargs dicts, would you consider that “an absolute non-issue” too ?
And I said in the question body that adding non-string keys to the dict in the body of the function should stay allowed in any case.
Sure, so ? Just because a developer can do something doesn’t mean the language shouldn’t include any check. From the top of my head, I’d cite the type constraint on the self argument, for methods accessed from the class.
Besides, the point since quite some time here is not whether or how to add the check in the implementation, but whether to consider an implementation detail a documented feature or not.
@boxed Same, I’m not (now) saying we should break that. But if you wanted to bring your API in accordance with the documentation (or my less-permissive version of it anyway), you could do it the 3113 way, by accepting a kwargs mixed-keys dict argument instead of a **kwargs one, in any function in which you need to accept non-identifier-keyed dicts.
As I said earlier, I’m 99% sure it would even reduce the processing load of the function calls (because it won’t explode your dict and recreate one after).
When I look at what’s at the called method set_postfix, it appears the intent is to accept a mapping, not keyword arguments, and the choice to use **kwargs is a poor one. Perhaps I’m being too fastidious, but is there another example of use in the wild, clear of those misgivings?