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:
a = 1
b = 2.0
functionWithDefaults(1,c = 3,*a,**b)
except TypeError as e:
print(repr(e))
try:
a = 1
b = 2.0
functionWithDefaults(1,*a,**b)
except TypeError as e:
print(repr(e))
try:
a = 1
b = 2.0
functionWithDefaults(c = 1, *a,**b)
except TypeError as e:
print(repr(e))
try:
a = 1
b = 2.0
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:
TypeError("'int' object is not iterable",)
TypeError("'int' object is not iterable",)
TypeError("'float' object is not iterable",)
TypeError('functionWithDefaults() argument after ** must be a mapping, not float',)
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:
TypeError('functionWithDefaults() argument after ** must be a mapping, not float',)
TypeError('functionWithDefaults() argument after ** must be a mapping, not float',)
TypeError('functionWithDefaults() argument after ** must be a mapping, not float',)
TypeError('functionWithDefaults() argument after ** must be a mapping, not float',)
The function itself doesn't matter obviously, it's never called. Please restore the old behavior, thanks.
Yours,
Kay
|
This is a consequence of issue27213. 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 issue27358 fixes it.
|
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
|
Here is a patch with smaller (in comparison with issue27358) 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
|