gh-87106: Fix inspect.signature.bind() handling of positional-only arguments with **kwargs (GH-103404)

This commit is contained in:
Jacob Walls 2024-05-13 03:56:09 -04:00 committed by GitHub
parent a705c1e449
commit 9c15202441
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 39 additions and 17 deletions

View file

@ -3106,6 +3106,8 @@ class Signature:
parameters_ex = ()
arg_vals = iter(args)
pos_only_param_in_kwargs = []
while True:
# Let's iterate through the positional arguments and corresponding
# parameters
@ -3126,10 +3128,10 @@ class Signature:
break
elif param.name in kwargs:
if param.kind == _POSITIONAL_ONLY:
msg = '{arg!r} parameter is positional only, ' \
'but was passed as a keyword'
msg = msg.format(arg=param.name)
raise TypeError(msg) from None
# Raise a TypeError once we are sure there is no
# **kwargs param later.
pos_only_param_in_kwargs.append(param)
continue
parameters_ex = (param,)
break
elif (param.kind == _VAR_KEYWORD or
@ -3211,20 +3213,22 @@ class Signature:
format(arg=param_name)) from None
else:
if param.kind == _POSITIONAL_ONLY:
# This should never happen in case of a properly built
# Signature object (but let's have this check here
# to ensure correct behaviour just in case)
raise TypeError('{arg!r} parameter is positional only, '
'but was passed as a keyword'. \
format(arg=param.name))
arguments[param_name] = arg_val
if kwargs:
if kwargs_param is not None:
# Process our '**kwargs'-like parameter
arguments[kwargs_param.name] = kwargs
elif pos_only_param_in_kwargs:
raise TypeError(
'got some positional-only arguments passed as '
'keyword arguments: {arg!r}'.format(
arg=', '.join(
param.name
for param in pos_only_param_in_kwargs
),
),
)
else:
raise TypeError(
'got an unexpected keyword argument {arg!r}'.format(