Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd0e27fc

Browse files
authored
Reject duplicateParamSpec.{args,kwargs} at call site (#18854)
Fixes#18035
1 parent715b982 commitd0e27fc

File tree

2 files changed

+64
-12
lines changed

2 files changed

+64
-12
lines changed

‎mypy/checkexpr.py‎

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2357,7 +2357,8 @@ def check_argument_count(
23572357

23582358
# Check for too many or few values for formals.
23592359
fori,kindinenumerate(callee.arg_kinds):
2360-
ifkind.is_required()andnotformal_to_actual[i]andnotis_unexpected_arg_error:
2360+
mapped_args=formal_to_actual[i]
2361+
ifkind.is_required()andnotmapped_argsandnotis_unexpected_arg_error:
23612362
# No actual for a mandatory formal
23622363
ifkind.is_positional():
23632364
self.msg.too_few_arguments(callee,context,actual_names)
@@ -2368,28 +2369,36 @@ def check_argument_count(
23682369
self.msg.missing_named_argument(callee,context,argname)
23692370
ok=False
23702371
elifnotkind.is_star()andis_duplicate_mapping(
2371-
formal_to_actual[i],actual_types,actual_kinds
2372+
mapped_args,actual_types,actual_kinds
23722373
):
23732374
ifself.chk.in_checked_function()orisinstance(
2374-
get_proper_type(actual_types[formal_to_actual[i][0]]),TupleType
2375+
get_proper_type(actual_types[mapped_args[0]]),TupleType
23752376
):
23762377
self.msg.duplicate_argument_value(callee,i,context)
23772378
ok=False
23782379
elif (
23792380
kind.is_named()
2380-
andformal_to_actual[i]
2381-
andactual_kinds[formal_to_actual[i][0]]notin [nodes.ARG_NAMED,nodes.ARG_STAR2]
2381+
andmapped_args
2382+
andactual_kinds[mapped_args[0]]notin [nodes.ARG_NAMED,nodes.ARG_STAR2]
23822383
):
23832384
# Positional argument when expecting a keyword argument.
23842385
self.msg.too_many_positional_arguments(callee,context)
23852386
ok=False
2386-
elif (
2387-
callee.param_spec()isnotNone
2388-
andnotformal_to_actual[i]
2389-
andcallee.special_sig!="partial"
2390-
):
2391-
self.msg.too_few_arguments(callee,context,actual_names)
2392-
ok=False
2387+
elifcallee.param_spec()isnotNone:
2388+
ifnotmapped_argsandcallee.special_sig!="partial":
2389+
self.msg.too_few_arguments(callee,context,actual_names)
2390+
ok=False
2391+
eliflen(mapped_args)>1:
2392+
paramspec_entries=sum(
2393+
isinstance(get_proper_type(actual_types[k]),ParamSpecType)
2394+
forkinmapped_args
2395+
)
2396+
ifactual_kinds[mapped_args[0]]==nodes.ARG_STARandparamspec_entries>1:
2397+
self.msg.fail("ParamSpec.args should only be passed once",context)
2398+
ok=False
2399+
ifactual_kinds[mapped_args[0]]==nodes.ARG_STAR2andparamspec_entries>1:
2400+
self.msg.fail("ParamSpec.kwargs should only be passed once",context)
2401+
ok=False
23932402
returnok
23942403

23952404
defcheck_for_extra_actual_arguments(

‎test-data/unit/check-parameter-specification.test‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2560,3 +2560,46 @@ def fn(f: MiddlewareFactory[P]) -> Capture[P]: ...
25602560

25612561
reveal_type(fn(ServerErrorMiddleware)) # N: Revealed type is "__main__.Capture[[handler: Union[builtins.str, None] =, debug: builtins.bool =]]"
25622562
[builtins fixtures/paramspec.pyi]
2563+
2564+
[case testRunParamSpecDuplicateArgsKwargs]
2565+
from typing_extensions import ParamSpec, Concatenate
2566+
from typing import Callable, Union
2567+
2568+
_P = ParamSpec("_P")
2569+
2570+
def run(predicate: Callable[_P, None], *args: _P.args, **kwargs: _P.kwargs) -> None:
2571+
predicate(*args, *args, **kwargs) # E: ParamSpec.args should only be passed once
2572+
predicate(*args, **kwargs, **kwargs) # E: ParamSpec.kwargs should only be passed once
2573+
predicate(*args, *args, **kwargs, **kwargs) # E: ParamSpec.args should only be passed once \
2574+
# E: ParamSpec.kwargs should only be passed once
2575+
copy_args = args
2576+
copy_kwargs = kwargs
2577+
predicate(*args, *copy_args, **kwargs) # E: ParamSpec.args should only be passed once
2578+
predicate(*copy_args, *args, **kwargs) # E: ParamSpec.args should only be passed once
2579+
predicate(*args, **copy_kwargs, **kwargs) # E: ParamSpec.kwargs should only be passed once
2580+
predicate(*args, **kwargs, **copy_kwargs) # E: ParamSpec.kwargs should only be passed once
2581+
2582+
def run2(predicate: Callable[Concatenate[int, _P], None], *args: _P.args, **kwargs: _P.kwargs) -> None:
2583+
predicate(*args, *args, **kwargs) # E: ParamSpec.args should only be passed once \
2584+
# E: Argument 1 has incompatible type "*_P.args"; expected "int"
2585+
predicate(*args, **kwargs, **kwargs) # E: ParamSpec.kwargs should only be passed once \
2586+
# E: Argument 1 has incompatible type "*_P.args"; expected "int"
2587+
predicate(1, *args, *args, **kwargs) # E: ParamSpec.args should only be passed once
2588+
predicate(1, *args, **kwargs, **kwargs) # E: ParamSpec.kwargs should only be passed once
2589+
predicate(1, *args, *args, **kwargs, **kwargs) # E: ParamSpec.args should only be passed once \
2590+
# E: ParamSpec.kwargs should only be passed once
2591+
copy_args = args
2592+
copy_kwargs = kwargs
2593+
predicate(1, *args, *copy_args, **kwargs) # E: ParamSpec.args should only be passed once
2594+
predicate(1, *copy_args, *args, **kwargs) # E: ParamSpec.args should only be passed once
2595+
predicate(1, *args, **copy_kwargs, **kwargs) # E: ParamSpec.kwargs should only be passed once
2596+
predicate(1, *args, **kwargs, **copy_kwargs) # E: ParamSpec.kwargs should only be passed once
2597+
2598+
def run3(predicate: Callable[Concatenate[int, str, _P], None], *args: _P.args, **kwargs: _P.kwargs) -> None:
2599+
base_ok: tuple[int, str]
2600+
predicate(*base_ok, *args, **kwargs)
2601+
base_bad: tuple[Union[int, str], ...]
2602+
predicate(*base_bad, *args, **kwargs) # E: Argument 1 has incompatible type "*Tuple[Union[int, str], ...]"; expected "int" \
2603+
# E: Argument 1 has incompatible type "*Tuple[Union[int, str], ...]"; expected "str" \
2604+
# E: Argument 1 has incompatible type "*Tuple[Union[int, str], ...]"; expected "_P.args"
2605+
[builtins fixtures/paramspec.pyi]

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp