Skip to content
Merged
14 changes: 14 additions & 0 deletions Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -2943,6 +2943,8 @@ def __init__(self, parameters=None, *, return_annotation=_empty,
params = OrderedDict()
top_kind = _POSITIONAL_ONLY
seen_default = False
var_positional_count = 0
var_keyword_count = 0

for param in parameters:
kind = param.kind
Expand Down Expand Up @@ -2971,6 +2973,18 @@ def __init__(self, parameters=None, *, return_annotation=_empty,
# There is a default for this parameter.
seen_default = True

if kind == _VAR_POSITIONAL:
var_positional_count += 1
if var_positional_count > 1:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems, *_count actually didn't count anything, isn't? I suggest use bool values instead and rename variables to something like seen_var_positional.

msg = 'more than one var positional parameter'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per glossary, probably it is better to use "var-positional" (and "var-keyword") terms.

raise ValueError(msg)

if kind == _VAR_KEYWORD:
var_keyword_count += 1
if var_keyword_count > 1:
msg = 'more than one var keyword parameter'
raise ValueError(msg)

if name in params:
msg = 'duplicate parameter name: {!r}'.format(name)
raise ValueError(msg)
Expand Down
8 changes: 8 additions & 0 deletions Lib/test/test_inspect/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -2992,6 +2992,14 @@ def test2(pod=42, /):
with self.assertRaisesRegex(ValueError, 'follows default argument'):
S((pkd, pk))

second_args = args.replace(name="second_args")
with self.assertRaisesRegex(ValueError, 'more than one var positional parameter'):
S((args, second_args))

second_kwargs = kwargs.replace(name="second_kwargs")
with self.assertRaisesRegex(ValueError, 'more than one var keyword parameter'):
S((kwargs, second_kwargs))

def test_signature_object_pickle(self):
def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
foo_partial = functools.partial(foo, a=1)
Expand Down
1 change: 1 addition & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Eitan Adler
Anton Afanasyev
Ali Afshar
Nitika Agarwal
Maxim Ageev
Anjani Agrawal
Pablo S. Blum de Aguiar
Jim Ahlstrom
Expand Down
Loading