_KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY
_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:
"""Represents a parameter in a function signature.
empty = _empty
def __init__(self, name, kind, *, default=_empty, annotation=_empty):
-
- if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD,
- _VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD):
- raise ValueError("invalid value for 'Parameter.kind' attribute")
- self._kind = kind
-
+ try:
+ self._kind = _ParameterKind(kind)
+ except ValueError:
+ raise ValueError(f'value {kind!r} is not a valid Parameter.kind')
if default is not _empty:
- if kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
- msg = '{} parameters cannot have default values'.format(kind)
+ if self._kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
+ msg = '{} parameters cannot have default values'
+ msg = msg.format(_get_paramkind_descr(self._kind))
raise ValueError(msg)
self._default = default
self._annotation = annotation
raise ValueError('name is a required attribute for Parameter')
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():
# These are implicit arguments generated by comprehensions. In
# order to provide a friendlier interface to users, we recast
# their name as "implicitN" and treat them as positional-only.
# See issue 19611.
- if kind != _POSITIONAL_OR_KEYWORD:
- raise ValueError(
- 'implicit arguments must be passed in as {}'.format(
- _POSITIONAL_OR_KEYWORD
- )
+ if self._kind != _POSITIONAL_OR_KEYWORD:
+ msg = (
+ 'implicit arguments must be passed as '
+ 'positional or keyword arguments, not {}'
)
+ msg = msg.format(_get_paramkind_descr(self._kind))
+ raise ValueError(msg)
self._kind = _POSITIONAL_ONLY
name = 'implicit{}'.format(name[1:])
name = param.name
if kind < top_kind:
- msg = 'wrong parameter order: {!r} before {!r}'
- msg = msg.format(top_kind, kind)
+ msg = (
+ 'wrong parameter order: {} parameter before {} '
+ 'parameter'
+ )
+ msg = msg.format(_get_paramkind_descr(top_kind),
+ _get_paramkind_descr(kind))
raise ValueError(msg)
elif kind > top_kind:
kind_defaults = False
with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
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):
def setUp(self):
self.assertIs(p.annotation, p.empty)
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')
with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
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.KEYWORD_ONLY)
@cpython_only
def test_signature_parameter_implicit(self):
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)
param = inspect.Parameter(