-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Pass literals as kwargs #10237
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Pass literals as kwargs #10237
Changes from all commits
cc18c72
9ba8f19
8559ee2
056925e
bacade7
042653c
be86dbf
49b2599
b45ad90
4df3f99
0d7a373
0152d30
7838906
80359a1
837d6a0
7c9090a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ | |
from contextlib import contextmanager | ||
import itertools | ||
from typing import ( | ||
cast, Dict, Set, List, Tuple, Callable, Union, Optional, Sequence, Iterator | ||
cast, Dict, Set, List, Tuple, Callable, Union, Optional, Sequence, Iterator, Iterable | ||
) | ||
from typing_extensions import ClassVar, Final, overload, TypeAlias as _TypeAlias | ||
|
||
|
@@ -69,7 +69,7 @@ | |
try_expanding_sum_type_to_union, tuple_fallback, make_simplified_union, | ||
true_only, false_only, erase_to_union_or_bound, function_type, | ||
callable_type, try_getting_str_literals, custom_special_method, | ||
is_literal_type_like, simple_literal_type, | ||
is_literal_type_like, simple_literal_type, try_getting_str_literals_from_type | ||
) | ||
from mypy.message_registry import ErrorMessage | ||
import mypy.errorcodes as codes | ||
|
@@ -1490,6 +1490,27 @@ def check_for_extra_actual_arguments(self, | |
context) | ||
is_unexpected_arg_error = True | ||
ok = False | ||
elif (isinstance(actual_type, Instance) and | ||
actual_type.type.has_base('typing.Mapping')): | ||
any_type = AnyType(TypeOfAny.special_form) | ||
mapping_info = self.chk.named_generic_type('typing.Mapping', | ||
[any_type, any_type]).type | ||
supertype = map_instance_to_supertype(actual_type, mapping_info) | ||
if messages and supertype.args: | ||
args = try_getting_str_literals_from_type(supertype.args[0]) | ||
if args and nodes.ARG_STAR2 not in callee.arg_kinds: | ||
messages.unexpected_keyword_argument( | ||
callee, args[0], supertype.args[0], context) | ||
is_unexpected_arg_error = True | ||
elif (args and nodes.ARG_POS in callee.arg_kinds and | ||
not all(arg in callee.arg_names for arg in args) and | ||
isinstance(actual_names, Iterable)): | ||
act_names = [name for name, kind in | ||
zip(iter(actual_names), actual_kinds) | ||
if kind != nodes.ARG_STAR2] | ||
messages.too_few_arguments(callee, context, act_names) | ||
ok = False | ||
|
||
# *args/**kwargs can be applied even if the function takes a fixed | ||
# number of positional arguments. This may succeed at runtime. | ||
|
||
|
@@ -4026,12 +4047,22 @@ def is_valid_var_arg(self, typ: Type) -> bool: | |
|
||
def is_valid_keyword_var_arg(self, typ: Type) -> bool: | ||
"""Is a type valid as a **kwargs argument?""" | ||
mapping_type = self.chk.named_generic_type( | ||
'typing.Mapping', [self.named_type('builtins.str'), AnyType(TypeOfAny.special_form)]) | ||
typ = get_proper_type(typ) | ||
|
||
ret = ( | ||
is_subtype(typ, self.chk.named_generic_type('typing.Mapping', | ||
[self.named_type('builtins.str'), AnyType(TypeOfAny.special_form)])) or | ||
is_subtype(typ, self.chk.named_generic_type('typing.Mapping', | ||
[UninhabitedType(), UninhabitedType()])) or | ||
isinstance(typ, ParamSpecType) | ||
is_subtype(typ, mapping_type) or | ||
(isinstance(typ, Instance) and | ||
is_subtype(typ, self.chk.named_type('typing.Mapping')) and | ||
try_getting_str_literals_from_type(map_instance_to_supertype( | ||
typ, mapping_type.type).args[0]) is not None) or | ||
# This condition is to avoid false-positive errors when empty dictionaries are | ||
# passed with double-stars (e.g., **{})。The type of empty dicts is inferred to be | ||
# dict[<nothing>, <nothing>], which is not a subtype of Mapping[str, Any]。 | ||
is_subtype(typ, self.chk.named_generic_type('typing.Mapping', | ||
[UninhabitedType(), UninhabitedType()])) or | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for being late. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @momohatt Thanks! |
||
isinstance(typ, ParamSpecType) | ||
) | ||
if self.chk.options.python_version[0] < 3: | ||
ret = ret or is_subtype(typ, self.chk.named_generic_type('typing.Mapping', | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#12699 deleted
messages
in favor ofself.msg
.