fix(checker): stabilize call error message

display missing arguments in a stable format, similar to how native Python does
This commit is contained in:
2026-05-29 19:08:13 +02:00
parent 95b218fbed
commit 13c19db818

View File

@@ -311,12 +311,12 @@ class Checker(
} }
set_args: set[str] = set() set_args: set[str] = set()
required_positional: set[str] = { required_positional: list[str] = [
arg.name for arg in function.pos_args + function.args if arg.required arg.name for arg in function.pos_args + function.args if arg.required
} ]
required_keyword: set[str] = { required_keyword: list[str] = [
arg.name for arg in function.kw_args if arg.required arg.name for arg in function.kw_args if arg.required
} ]
mapped: list[MappedArgument] = [] mapped: list[MappedArgument] = []
@@ -336,9 +336,12 @@ class Checker(
else: else:
self.error(arg[0].location, "Too many positional arguments") self.error(arg[0].location, "Too many positional arguments")
break break
required_positional.discard(param.name) name: str = param.name
required_keyword.discard(param.name) if name in required_positional:
set_args.add(param.name) required_positional.remove(name)
if name in required_keyword:
required_keyword.remove(name)
set_args.add(name)
mapped.append( mapped.append(
MappedArgument( MappedArgument(
expr=arg[0], expr=arg[0],
@@ -359,8 +362,10 @@ class Checker(
self.error(arg[0].location, f"Unknown keyword argument '{name}'") self.error(arg[0].location, f"Unknown keyword argument '{name}'")
continue continue
param = kw_params.pop(name) param = kw_params.pop(name)
required_positional.discard(name) if name in required_positional:
required_keyword.discard(name) required_positional.remove(name)
if name in required_keyword:
required_keyword.remove(name)
set_args.add(name) set_args.add(name)
mapped.append( mapped.append(
MappedArgument( MappedArgument(
@@ -370,16 +375,28 @@ class Checker(
) )
) )
def join_args(args: list[str]) -> str:
args = list(map(lambda a: f"'{a}'", args))
if len(args) == 0:
return ""
if len(args) == 1:
return args[0]
return ", ".join(args[:-1]) + " and " + args[-1]
if len(required_positional) != 0: if len(required_positional) != 0:
plural: str = "" if len(required_positional) == 1 else "s"
args: str = join_args(required_positional)
self.error( self.error(
call.location, call.location,
f"Missing required positional arguments: {required_positional}", f"Missing required positional argument{plural}: {args}",
) )
if len(required_keyword) != 0: if len(required_keyword) != 0:
plural: str = "" if len(required_keyword) == 1 else "s"
args: str = join_args(required_keyword)
self.error( self.error(
call.location, call.location,
f"Missing required keyword arguments: {required_keyword}", f"Missing required keyword argument{plural}: {args}",
) )
return mapped return mapped