bpo-33197: Update a error message of invalid inspect.Parameters. (GH-6636)

This commit is contained in:
Dong-hee Na 2018-05-30 00:04:08 +09:00 committed by Yury Selivanov
parent 9551f77192
commit a9cab433bb
3 changed files with 55 additions and 19 deletions

View File

@ -2402,6 +2402,16 @@ _VAR_POSITIONAL = _ParameterKind.VAR_POSITIONAL
_KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY _KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY
_VAR_KEYWORD = _ParameterKind.VAR_KEYWORD _VAR_KEYWORD = _ParameterKind.VAR_KEYWORD
_PARAM_NAME_MAPPING = {
_POSITIONAL_ONLY: 'positional-only',
_POSITIONAL_OR_KEYWORD: 'positional or keyword',
_VAR_POSITIONAL: 'variadic positional',
_KEYWORD_ONLY: 'keyword-only',
_VAR_KEYWORD: 'variadic keyword'
}
_get_paramkind_descr = _PARAM_NAME_MAPPING.__getitem__
class Parameter: class Parameter:
"""Represents a parameter in a function signature. """Represents a parameter in a function signature.
@ -2436,15 +2446,14 @@ class Parameter:
empty = _empty empty = _empty
def __init__(self, name, kind, *, default=_empty, annotation=_empty): def __init__(self, name, kind, *, default=_empty, annotation=_empty):
try:
if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD, self._kind = _ParameterKind(kind)
_VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD): except ValueError:
raise ValueError("invalid value for 'Parameter.kind' attribute") raise ValueError(f'value {kind!r} is not a valid Parameter.kind')
self._kind = kind
if default is not _empty: if default is not _empty:
if kind in (_VAR_POSITIONAL, _VAR_KEYWORD): if self._kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
msg = '{} parameters cannot have default values'.format(kind) msg = '{} parameters cannot have default values'
msg = msg.format(_get_paramkind_descr(self._kind))
raise ValueError(msg) raise ValueError(msg)
self._default = default self._default = default
self._annotation = annotation self._annotation = annotation
@ -2453,19 +2462,21 @@ class Parameter:
raise ValueError('name is a required attribute for Parameter') raise ValueError('name is a required attribute for Parameter')
if not isinstance(name, str): if not isinstance(name, str):
raise TypeError("name must be a str, not a {!r}".format(name)) msg = 'name must be a str, not a {}'.format(type(name).__name__)
raise TypeError(msg)
if name[0] == '.' and name[1:].isdigit(): if name[0] == '.' and name[1:].isdigit():
# These are implicit arguments generated by comprehensions. In # These are implicit arguments generated by comprehensions. In
# order to provide a friendlier interface to users, we recast # order to provide a friendlier interface to users, we recast
# their name as "implicitN" and treat them as positional-only. # their name as "implicitN" and treat them as positional-only.
# See issue 19611. # See issue 19611.
if kind != _POSITIONAL_OR_KEYWORD: if self._kind != _POSITIONAL_OR_KEYWORD:
raise ValueError( msg = (
'implicit arguments must be passed in as {}'.format( 'implicit arguments must be passed as '
_POSITIONAL_OR_KEYWORD 'positional or keyword arguments, not {}'
)
) )
msg = msg.format(_get_paramkind_descr(self._kind))
raise ValueError(msg)
self._kind = _POSITIONAL_ONLY self._kind = _POSITIONAL_ONLY
name = 'implicit{}'.format(name[1:]) name = 'implicit{}'.format(name[1:])
@ -2736,8 +2747,12 @@ class Signature:
name = param.name name = param.name
if kind < top_kind: if kind < top_kind:
msg = 'wrong parameter order: {!r} before {!r}' msg = (
msg = msg.format(top_kind, kind) 'wrong parameter order: {} parameter before {} '
'parameter'
)
msg = msg.format(_get_paramkind_descr(top_kind),
_get_paramkind_descr(kind))
raise ValueError(msg) raise ValueError(msg)
elif kind > top_kind: elif kind > top_kind:
kind_defaults = False kind_defaults = False

View File

@ -1499,6 +1499,20 @@ class TestGetcallargsFunctions(unittest.TestCase):
with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"): with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
inspect.getcallargs(f6) inspect.getcallargs(f6)
# bpo-33197
with self.assertRaisesRegex(ValueError,
'variadic keyword parameters cannot'
' have default values'):
inspect.Parameter("foo", kind=inspect.Parameter.VAR_KEYWORD,
default=42)
with self.assertRaisesRegex(ValueError,
"value 5 is not a valid Parameter.kind"):
inspect.Parameter("bar", kind=5, default=42)
with self.assertRaisesRegex(TypeError,
'name must be a str, not a int'):
inspect.Parameter(123, kind=4)
class TestGetcallargsMethods(TestGetcallargsFunctions): class TestGetcallargsMethods(TestGetcallargsFunctions):
def setUp(self): def setUp(self):
@ -3099,7 +3113,8 @@ class TestParameterObject(unittest.TestCase):
self.assertIs(p.annotation, p.empty) self.assertIs(p.annotation, p.empty)
self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY) self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
with self.assertRaisesRegex(ValueError, 'invalid value'): with self.assertRaisesRegex(ValueError, "value '123' is "
"not a valid Parameter.kind"):
inspect.Parameter('foo', default=10, kind='123') inspect.Parameter('foo', default=10, kind='123')
with self.assertRaisesRegex(ValueError, 'not a valid parameter name'): with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
@ -3189,7 +3204,9 @@ class TestParameterObject(unittest.TestCase):
self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD) self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
self.assertNotEqual(p2, p) self.assertNotEqual(p2, p)
with self.assertRaisesRegex(ValueError, 'invalid value for'): with self.assertRaisesRegex(ValueError,
"value <class 'inspect._empty'> "
"is not a valid Parameter.kind"):
p2 = p2.replace(kind=p2.empty) p2 = p2.replace(kind=p2.empty)
p2 = p2.replace(kind=p2.KEYWORD_ONLY) p2 = p2.replace(kind=p2.KEYWORD_ONLY)
@ -3202,7 +3219,9 @@ class TestParameterObject(unittest.TestCase):
@cpython_only @cpython_only
def test_signature_parameter_implicit(self): def test_signature_parameter_implicit(self):
with self.assertRaisesRegex(ValueError, with self.assertRaisesRegex(ValueError,
'implicit arguments must be passed in as'): 'implicit arguments must be passed as '
'positional or keyword arguments, '
'not positional-only'):
inspect.Parameter('.0', kind=inspect.Parameter.POSITIONAL_ONLY) inspect.Parameter('.0', kind=inspect.Parameter.POSITIONAL_ONLY)
param = inspect.Parameter( param = inspect.Parameter(

View File

@ -0,0 +1,2 @@
Update error message when constructing invalid inspect.Parameters
Patch by Dong-hee Na.