I've noticed, to my surprise, that in a function call, I could unpack a dict with strings that weren't even valid python identifiers.
It's surprising to me since argument names must be identifiers, so allowing a function call to unpack a **kwargs that has non-identifiers, with no run time error, doesn't seem healthy (since it could bury problems deeper that where they actually occur).
Unless there's an actual use to being able to do this, in which case my question becomes "what would that use be?".
Example code
Consider this function:
def foo(**kwargs):
first_key, first_val = next(iter(kwargs.items()))
print(f"{first_key=}, {first_val=}")
return kwargs
This shows that, within a function call, you can't unpack a dict that has has integer keys, which is EXPECTED.
>>> t = foo(**{1: 2, 3: 4})
TypeError Traceback (most recent call last)
...
TypeError: foo() keywords must be strings
What is really not expected, and surprising, is that you can, on the other hand, unpack a dict with string keys, even if these are not valid python identifiers:
>>> t = foo(**{'not an identifier': 1, '12': 12, ',(*&$)': 100})
first_key='not an identifier', first_val=1
>>> t
{'not an identifier': 1, '12': 12, ',(*&$)': 100}