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

Reject duplicateParamSpec.{args,kwargs} at call site#18854

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Show file tree
Hide file tree
Changes from1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
NextNext commit
Reject duplicate ParamSpec components
  • Loading branch information
@sterliakov
sterliakov committedMar 30, 2025
commitd3e7a9e34987cbf2ba8b446759c5ece77e9960fe
29 changes: 17 additions & 12 deletionsmypy/checkexpr.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2357,7 +2357,8 @@ def check_argument_count(

# Check for too many or few values for formals.
for i, kind in enumerate(callee.arg_kinds):
if kind.is_required() and not formal_to_actual[i] and not is_unexpected_arg_error:
mapped_args = formal_to_actual[i]
if kind.is_required() and not mapped_args and not is_unexpected_arg_error:
# No actual for a mandatory formal
if kind.is_positional():
self.msg.too_few_arguments(callee, context, actual_names)
Expand All@@ -2368,28 +2369,32 @@ def check_argument_count(
self.msg.missing_named_argument(callee, context, argname)
ok = False
elif not kind.is_star() and is_duplicate_mapping(
formal_to_actual[i], actual_types, actual_kinds
mapped_args, actual_types, actual_kinds
):
if self.chk.in_checked_function() or isinstance(
get_proper_type(actual_types[formal_to_actual[i][0]]), TupleType
get_proper_type(actual_types[mapped_args[0]]), TupleType
):
self.msg.duplicate_argument_value(callee, i, context)
ok = False
elif (
kind.is_named()
andformal_to_actual[i]
and actual_kinds[formal_to_actual[i][0]] not in [nodes.ARG_NAMED, nodes.ARG_STAR2]
andmapped_args
and actual_kinds[mapped_args[0]] not in [nodes.ARG_NAMED, nodes.ARG_STAR2]
):
# Positional argument when expecting a keyword argument.
self.msg.too_many_positional_arguments(callee, context)
ok = False
elif (
callee.param_spec() is not None
and not formal_to_actual[i]
and callee.special_sig != "partial"
):
self.msg.too_few_arguments(callee, context, actual_names)
ok = False
elif callee.param_spec() is not None:
if not mapped_args and callee.special_sig != "partial":
self.msg.too_few_arguments(callee, context, actual_names)
ok = False
elif len(mapped_args) > 1:
if actual_kinds[mapped_args[0]] == nodes.ARG_STAR:
self.msg.fail("ParamSpec.args should only be passed once", context)
ok = False
if actual_kinds[mapped_args[0]] == nodes.ARG_STAR2:
self.msg.fail("ParamSpec.kwargs should only be passed once", context)
ok = False
return ok

def check_for_extra_actual_arguments(
Expand Down
23 changes: 23 additions & 0 deletionstest-data/unit/check-parameter-specification.test
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2560,3 +2560,26 @@ def fn(f: MiddlewareFactory[P]) -> Capture[P]: ...

reveal_type(fn(ServerErrorMiddleware)) # N: Revealed type is "__main__.Capture[[handler: Union[builtins.str, None] =, debug: builtins.bool =]]"
[builtins fixtures/paramspec.pyi]

[case testRunParamSpecDuplicateArgsKwargs]
from typing_extensions import ParamSpec, Concatenate
from typing import Callable

_P = ParamSpec("_P")

def run(predicate: Callable[_P, None], *args: _P.args, **kwargs: _P.kwargs) -> None:
predicate(*args, *args, **kwargs) # E: ParamSpec.args should only be passed once
predicate(*args, **kwargs, **kwargs) # E: ParamSpec.kwargs should only be passed once
predicate(*args, *args, **kwargs, **kwargs) # E: ParamSpec.args should only be passed once \
# E: ParamSpec.kwargs should only be passed once

def run2(predicate: Callable[Concatenate[int, _P], None], *args: _P.args, **kwargs: _P.kwargs) -> None:
predicate(*args, *args, **kwargs) # E: ParamSpec.args should only be passed once \
# E: Argument 1 has incompatible type "*_P.args"; expected "int"
predicate(*args, **kwargs, **kwargs) # E: ParamSpec.kwargs should only be passed once \
# E: Argument 1 has incompatible type "*_P.args"; expected "int"
predicate(1, *args, *args, **kwargs) # E: ParamSpec.args should only be passed once
predicate(1, *args, **kwargs, **kwargs) # E: ParamSpec.kwargs should only be passed once
predicate(1, *args, *args, **kwargs, **kwargs) # E: ParamSpec.args should only be passed once \
# E: ParamSpec.kwargs should only be passed once
[builtins fixtures/paramspec.pyi]
Loading

[8]ページ先頭

©2009-2025 Movatter.jp