Commit 86872753 authored by Yury Selivanov's avatar Yury Selivanov

Issue 24205: Improve inspect.Signature.bind() error messages.

parent fee05dae
...@@ -2762,7 +2762,7 @@ class Signature: ...@@ -2762,7 +2762,7 @@ class Signature:
parameters_ex = (param,) parameters_ex = (param,)
break break
else: else:
msg = '{arg!r} parameter lacking default value' msg = 'missing a required argument: {arg!r}'
msg = msg.format(arg=param.name) msg = msg.format(arg=param.name)
raise TypeError(msg) from None raise TypeError(msg) from None
else: else:
...@@ -2775,7 +2775,8 @@ class Signature: ...@@ -2775,7 +2775,8 @@ class Signature:
if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY): if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
# Looks like we have no parameter for this positional # Looks like we have no parameter for this positional
# argument # argument
raise TypeError('too many positional arguments') raise TypeError(
'too many positional arguments') from None
if param.kind == _VAR_POSITIONAL: if param.kind == _VAR_POSITIONAL:
# We have an '*args'-like argument, let's fill it with # We have an '*args'-like argument, let's fill it with
...@@ -2787,8 +2788,9 @@ class Signature: ...@@ -2787,8 +2788,9 @@ class Signature:
break break
if param.name in kwargs: if param.name in kwargs:
raise TypeError('multiple values for argument ' raise TypeError(
'{arg!r}'.format(arg=param.name)) 'multiple values for argument {arg!r}'.format(
arg=param.name)) from None
arguments[param.name] = arg_val arguments[param.name] = arg_val
...@@ -2817,7 +2819,7 @@ class Signature: ...@@ -2817,7 +2819,7 @@ class Signature:
# arguments. # arguments.
if (not partial and param.kind != _VAR_POSITIONAL and if (not partial and param.kind != _VAR_POSITIONAL and
param.default is _empty): param.default is _empty):
raise TypeError('{arg!r} parameter lacking default value'. \ raise TypeError('missing a required argument: {arg!r}'. \
format(arg=param_name)) from None format(arg=param_name)) from None
else: else:
...@@ -2836,7 +2838,9 @@ class Signature: ...@@ -2836,7 +2838,9 @@ class Signature:
# Process our '**kwargs'-like parameter # Process our '**kwargs'-like parameter
arguments[kwargs_param.name] = kwargs arguments[kwargs_param.name] = kwargs
else: else:
raise TypeError('too many keyword arguments') raise TypeError(
'got an unexpected keyword argument {arg!r}'.format(
arg=next(iter(kwargs))))
return self._bound_arguments_cls(self, arguments) return self._bound_arguments_cls(self, arguments)
......
...@@ -2891,7 +2891,9 @@ class TestSignatureBind(unittest.TestCase): ...@@ -2891,7 +2891,9 @@ class TestSignatureBind(unittest.TestCase):
self.call(test, 1) self.call(test, 1)
with self.assertRaisesRegex(TypeError, 'too many positional arguments'): with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
self.call(test, 1, spam=10) self.call(test, 1, spam=10)
with self.assertRaisesRegex(TypeError, 'too many keyword arguments'): with self.assertRaisesRegex(
TypeError, "got an unexpected keyword argument 'spam'"):
self.call(test, spam=1) self.call(test, spam=1)
def test_signature_bind_var(self): def test_signature_bind_var(self):
...@@ -2916,10 +2918,12 @@ class TestSignatureBind(unittest.TestCase): ...@@ -2916,10 +2918,12 @@ class TestSignatureBind(unittest.TestCase):
with self.assertRaisesRegex(TypeError, 'too many positional arguments'): with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
self.call(test, 1, 2, 3, 4) self.call(test, 1, 2, 3, 4)
with self.assertRaisesRegex(TypeError, "'b' parameter lacking default"): with self.assertRaisesRegex(TypeError,
"missing a required argument: 'b'"):
self.call(test, 1) self.call(test, 1)
with self.assertRaisesRegex(TypeError, "'a' parameter lacking default"): with self.assertRaisesRegex(TypeError,
"missing a required argument: 'a'"):
self.call(test) self.call(test)
def test(a, b, c=10): def test(a, b, c=10):
...@@ -2992,7 +2996,7 @@ class TestSignatureBind(unittest.TestCase): ...@@ -2992,7 +2996,7 @@ class TestSignatureBind(unittest.TestCase):
def test(a, *, foo=1, bar): def test(a, *, foo=1, bar):
return foo return foo
with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(TypeError,
"'bar' parameter lacking default value"): "missing a required argument: 'bar'"):
self.call(test, 1) self.call(test, 1)
def test(foo, *, bar): def test(foo, *, bar):
...@@ -3000,8 +3004,9 @@ class TestSignatureBind(unittest.TestCase): ...@@ -3000,8 +3004,9 @@ class TestSignatureBind(unittest.TestCase):
self.assertEqual(self.call(test, 1, bar=2), (1, 2)) self.assertEqual(self.call(test, 1, bar=2), (1, 2))
self.assertEqual(self.call(test, bar=2, foo=1), (1, 2)) self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(
'too many keyword arguments'): TypeError, "got an unexpected keyword argument 'spam'"):
self.call(test, bar=2, foo=1, spam=10) self.call(test, bar=2, foo=1, spam=10)
with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(TypeError,
...@@ -3012,12 +3017,13 @@ class TestSignatureBind(unittest.TestCase): ...@@ -3012,12 +3017,13 @@ class TestSignatureBind(unittest.TestCase):
'too many positional arguments'): 'too many positional arguments'):
self.call(test, 1, 2, bar=2) self.call(test, 1, 2, bar=2)
with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(
'too many keyword arguments'): TypeError, "got an unexpected keyword argument 'spam'"):
self.call(test, 1, bar=2, spam='ham') self.call(test, 1, bar=2, spam='ham')
with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(TypeError,
"'bar' parameter lacking default value"): "missing a required argument: 'bar'"):
self.call(test, 1) self.call(test, 1)
def test(foo, *, bar, **bin): def test(foo, *, bar, **bin):
...@@ -3029,7 +3035,7 @@ class TestSignatureBind(unittest.TestCase): ...@@ -3029,7 +3035,7 @@ class TestSignatureBind(unittest.TestCase):
self.assertEqual(self.call(test, spam='ham', foo=1, bar=2), self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
(1, 2, {'spam': 'ham'})) (1, 2, {'spam': 'ham'}))
with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(TypeError,
"'foo' parameter lacking default value"): "missing a required argument: 'foo'"):
self.call(test, spam='ham', bar=2) self.call(test, spam='ham', bar=2)
self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10), self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
(1, 2, {'bin': 1, 'spam': 10})) (1, 2, {'bin': 1, 'spam': 10}))
...@@ -3094,7 +3100,9 @@ class TestSignatureBind(unittest.TestCase): ...@@ -3094,7 +3100,9 @@ class TestSignatureBind(unittest.TestCase):
return a, args return a, args
sig = inspect.signature(test) sig = inspect.signature(test)
with self.assertRaisesRegex(TypeError, "too many keyword arguments"): with self.assertRaisesRegex(
TypeError, "got an unexpected keyword argument 'args'"):
sig.bind(a=0, args=1) sig.bind(a=0, args=1)
def test(*args, **kwargs): def test(*args, **kwargs):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment