-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
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
Regression for star argument parameter error messages #72444
Comments
Hello, there is a regression in the beta (alpha 4 was ok) for this kind of code: print("Complex call with both invalid star list and star arguments:") try: functionWithDefaults(1,c = 3,*a,**b)
except TypeError as e:
print(repr(e)) try: functionWithDefaults(1,*a,**b)
except TypeError as e:
print(repr(e)) try: functionWithDefaults(c = 1, *a,**b)
except TypeError as e:
print(repr(e)) try: functionWithDefaults(*a,**b)
except TypeError as e:
print(repr(e)) This prints with beta1 3.6 Complex call with both invalid star list and star arguments: The later message is what they all probably should be like. This is 3.5 output: Complex call with both invalid star list and star arguments: The function itself doesn't matter obviously, it's never called. Please restore the old behavior, thanks. Yours, |
This is a consequence of bpo-27213. Actually there are two issues: with var-positional and var-keyword arguments. But Python 3.5 is not consistent. It raises an exception with less detailed message if there are multiple var-positional or var-keyword arguments. Var-positional arguments: >>> f(*0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() argument after * must be an iterable, not int
>>> f(1, *0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() argument after * must be an iterable, not int
>>> f(*[], *0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable Python 3.6 just raises the latter message in case of positional arguments and single var-positional argument. >>> f(*0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() argument after * must be an iterable, not int
>>> f(1, *0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> f(*[], *0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable This issue can't be fixed without adding new bytecode (BUILD_TUPLE_UNPACK_WITH_CALL). If it will be decided to fix it in 3.6, it may be worth to backport this to 3.5. Var-keyword arguments: Python 3.5: >>> f(**[])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() argument after ** must be a mapping, not list
>>> f(x=1, **0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() argument after ** must be a mapping, not int
>>> f(x=1, **[])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() argument after ** must be a mapping, not list
>>> f(**{}, **0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> f(**{}, **[])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not a mapping Python 3.6 raises less detailed error message in case of keyword arguments and single var-keyword argument. >>> f(**0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() argument after ** must be a mapping, not int
>>> f(**[])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() argument after ** must be a mapping, not list
>>> f(x=1, **0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> f(x=1, **[])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not a mapping
>>> f(**{}, **0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not a mapping
>>> f(**{}, **[])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not a mapping This issue can be fixed without changing bytecode. The patch faster_build_map_unpack_with_call.patch for bpo-27358 fixes it. |
Ned and Larry. Is it allowed to use the patch from bpo-27358 for fixing a regression in 3.6 and inconsistency in 3.5 for var-keyword arguments? The patch introduces new private function _PyDict_MergeEx() and touches the implementation of PyDict_Merge(). Maybe this can be fixed with smaller patch, but I don't know. Is it allowed to add new opcode BUILD_TUPLE_UNPACK_WITH_CALL for fixing a regression in 3.6 and inconsistency in 3.5 for var-positional arguments? This is the only way. The bytecode already was changed in a bugfix release of 3.5 for more serious need: fixing potential segfault or security issue (bpo-27286). |
It's too late to change this for 3.5. |
That is a fairly big change to go in now but the error message regression is also big. With a review from a core developer and assuming no other objections, I think this can go into 360b2. |
The whole point of having a beta release is to detect issues like this. |
Raymond, Larry's comment was about 3.5, not 3.6. See my comment above. |
Proposed patch fixes error message for var-positional arguments. It adds new opcode BUILD_TUPLE_UNPACK_WITH_CALL. >>> min(1, *2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: min() argument after * must be an iterable, not int
>>> min(*[1], *2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: min() argument after * must be an iterable, not int |
New changeset 88b319dfc909 by Serhiy Storchaka in branch '3.6': New changeset bde594cd8369 by Serhiy Storchaka in branch 'default': New changeset 40d7ce58ebd0 by Serhiy Storchaka in branch '3.5': New changeset a8168a52a56f by Serhiy Storchaka in branch '2.7': |
Here is a patch with smaller (in comparison with bpo-27358) change for 3.5 that improves error message when pass a non-mapping as second var-keyword argument. Unpatched: >>> f(**{'a': 1}, **[])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not a mapping
>>> f(**{'a': 1}, **0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable Patched: >>> f(**{'a': 1}, **[])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() argument after ** must be a mapping, not list
>>> f(**{'a': 1}, **0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() argument after ** must be a mapping, not int |
New changeset 35676cd72352 by Serhiy Storchaka in branch '3.5': |
Misc/NEWS
so that it is managed by towncrier #552Note: 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: