-
-
Notifications
You must be signed in to change notification settings - Fork 30.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disallow iterable argument unpacking after a keyword argument? #82741
Comments
Calls of the form f(name=value, *args) are currently legal syntax. The resulting argument binding is awkward, and almost never does what you want/expect it to: >>> def f(x, y, z):
... print(x, y, z)
...
>>> f(x=0, *(1, 2))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() got multiple values for argument 'x'
>>> f(y=0, *(1, 2))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() got multiple values for argument 'y'
>>> f(z=0, *(1, 2))
1 2 0 I'm not sure if this is intentional, or an oversight. Every other way of passing positional arguments after keyword arguments results in an error: f(kwarg=kwarg, arg) # SyntaxError: positional argument follows keyword argument
f(**kwargs, arg) # SyntaxError: positional argument follows keyword argument unpacking
f(**kwargs, *args) # SyntaxError: iterable argument unpacking follows keyword argument unpacking I think this case should raise a "SyntaxError: iterable argument unpacking follows keyword argument". I'd like to work on this if we believe it should be changed. |
I'd be +1 on this, but I'm worried about existing code relying on the functional use case from your example. If we are going to discourage it, I think we either have to:
|
I've found one occurrence of this in the CPython codebase, in test_ast.py. Basically it makes sure that the following expression parses and compiles correctly: f(1,2,c=3,*d,**e) I doubt that this is to protect against regressions in this specific syntax. More likely it's just trying to create as many of the different argument passing AST nodes as possible in one call (it's the only test for function calls with arguments). It can probably be slightly refactored: f(1,2,*c,d=3,**e) |
I’ve thought about it and I’m +1 on DeprecationWarning in 3.9 and SyntaxError in 3.10. Removing any type of legal function call is tricky, but this is such obscure, sneaky syntax that it’s likely an accident/bug if it does pop up (that’s how I discovered it). And every instance can be trivially refactored. |
Changes to the grammar of the language need to be discussed on python-dev (especially ones that can break existing code and ones that change syntax that has worked for many years). Arguably, this is something that should just go into a lint tool. |
Well, as you point out, f(z=0, *(1, 2)) is legal, and the parser doesn't know what the names of the keyword arguments are. SO this cannot be changed. |
The new release of flake8-bugbear is starting to flag positional argument unpacking that comes after keyword arguments in function calls as a style warning that fails. This is a good thing to catch because it can lead to unexpected side effects with function arguments and/or errors thrown by Python. See the following links for more details: - https://stackoverflow.com/questions/58961715/python-value-unpacking-order-in-method-parameters - python/cpython#82741 This changeset fixes a couple of instances where the positional argument unpacking was happening after keyword arguments were being provided. Signed-off-by: Carlo Costino <[email protected]>
The new release of flake8-bugbear is starting to flag positional argument unpacking that comes after keyword arguments in function calls as a style warning that fails. This is a good thing to catch because it can lead to unexpected side effects with function arguments and/or errors thrown by Python. See the following links for more details: - https://stackoverflow.com/questions/58961715/python-value-unpacking-order-in-method-parameters - python/cpython#82741 This changeset fixes a couple of instances where the positional argument unpacking was happening after keyword arguments were being provided. Signed-off-by: Carlo Costino <[email protected]>
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: