Skip to content

Commit 0c38b37

Browse files
sobolevntushar-deepsource
authored andcommitted
Refactor is_named_instance and refers_to_fullname (python#11961)
1 parent 1d2f162 commit 0c38b37

File tree

4 files changed

+35
-31
lines changed

4 files changed

+35
-31
lines changed

mypy/constraints.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
TupleType, TypedDictType, UnionType, Overloaded, ErasedType, PartialType, DeletedType,
99
UninhabitedType, TypeType, TypeVarId, TypeQuery, is_named_instance, TypeOfAny, LiteralType,
1010
ProperType, ParamSpecType, get_proper_type, TypeAliasType, is_union_with_any,
11-
callable_with_ellipsis
11+
callable_with_ellipsis,
12+
TUPLE_LIKE_INSTANCE_NAMES,
1213
)
1314
from mypy.maptype import map_instance_to_supertype
1415
import mypy.subtypes
@@ -501,11 +502,8 @@ def visit_instance(self, template: Instance) -> List[Constraint]:
501502
return res
502503
if isinstance(actual, AnyType):
503504
return self.infer_against_any(template.args, actual)
504-
if (isinstance(actual, TupleType) and
505-
(is_named_instance(template, 'typing.Iterable') or
506-
is_named_instance(template, 'typing.Container') or
507-
is_named_instance(template, 'typing.Sequence') or
508-
is_named_instance(template, 'typing.Reversible'))
505+
if (isinstance(actual, TupleType)
506+
and is_named_instance(template, TUPLE_LIKE_INSTANCE_NAMES)
509507
and self.direction == SUPERTYPE_OF):
510508
for item in actual.items:
511509
cb = infer_constraints(template.args[0], item, SUPERTYPE_OF)

mypy/semanal.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
TypeTranslator, TypeOfAny, TypeType, NoneType, PlaceholderType, TPDICT_NAMES, ProperType,
9595
get_proper_type, get_proper_types, TypeAliasType, TypeVarLikeType,
9696
PROTOCOL_NAMES, TYPE_ALIAS_NAMES, FINAL_TYPE_NAMES, FINAL_DECORATOR_NAMES,
97+
is_named_instance,
9798
)
9899
from mypy.typeops import function_type, get_type_vars
99100
from mypy.type_visitor import TypeQuery
@@ -1038,8 +1039,7 @@ def visit_decorator(self, dec: Decorator) -> None:
10381039
removed.append(i)
10391040
dec.func.is_abstract = True
10401041
self.check_decorated_function_is_method('abstractmethod', dec)
1041-
elif (refers_to_fullname(d, 'asyncio.coroutines.coroutine') or
1042-
refers_to_fullname(d, 'types.coroutine')):
1042+
elif refers_to_fullname(d, ('asyncio.coroutines.coroutine', 'types.coroutine')):
10431043
removed.append(i)
10441044
dec.func.is_awaitable_coroutine = True
10451045
elif refers_to_fullname(d, 'builtins.staticmethod'):
@@ -1052,9 +1052,10 @@ def visit_decorator(self, dec: Decorator) -> None:
10521052
dec.func.is_class = True
10531053
dec.var.is_classmethod = True
10541054
self.check_decorated_function_is_method('classmethod', dec)
1055-
elif (refers_to_fullname(d, 'builtins.property') or
1056-
refers_to_fullname(d, 'abc.abstractproperty') or
1057-
refers_to_fullname(d, 'functools.cached_property')):
1055+
elif refers_to_fullname(d, (
1056+
'builtins.property',
1057+
'abc.abstractproperty',
1058+
'functools.cached_property')):
10581059
removed.append(i)
10591060
dec.func.is_property = True
10601061
dec.var.is_property = True
@@ -1068,8 +1069,7 @@ def visit_decorator(self, dec: Decorator) -> None:
10681069
elif refers_to_fullname(d, 'typing.no_type_check'):
10691070
dec.var.type = AnyType(TypeOfAny.special_form)
10701071
no_type_check = True
1071-
elif (refers_to_fullname(d, 'typing.final') or
1072-
refers_to_fullname(d, 'typing_extensions.final')):
1072+
elif refers_to_fullname(d, FINAL_DECORATOR_NAMES):
10731073
if self.is_class_scope():
10741074
assert self.type is not None, "No type set at class scope"
10751075
if self.type.is_protocol:
@@ -5315,16 +5315,17 @@ def replace_implicit_first_type(sig: FunctionLike, new: Type) -> FunctionLike:
53155315
assert False
53165316

53175317

5318-
def refers_to_fullname(node: Expression, fullname: str) -> bool:
5318+
def refers_to_fullname(node: Expression, fullnames: Union[str, Tuple[str, ...]]) -> bool:
53195319
"""Is node a name or member expression with the given full name?"""
5320+
if not isinstance(fullnames, tuple):
5321+
fullnames = (fullnames,)
5322+
53205323
if not isinstance(node, RefExpr):
53215324
return False
5322-
if node.fullname == fullname:
5325+
if node.fullname in fullnames:
53235326
return True
53245327
if isinstance(node.node, TypeAlias):
5325-
target = get_proper_type(node.node.target)
5326-
if isinstance(target, Instance) and target.type.fullname == fullname:
5327-
return True
5328+
return is_named_instance(node.node.target, fullnames)
53285329
return False
53295330

53305331

mypy/subtypes.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
Type, AnyType, UnboundType, TypeVisitor, FormalArgument, NoneType,
88
Instance, TypeVarType, CallableType, TupleType, TypedDictType, UnionType, Overloaded,
99
ErasedType, PartialType, DeletedType, UninhabitedType, TypeType, is_named_instance,
10-
FunctionLike, TypeOfAny, LiteralType, get_proper_type, TypeAliasType, ParamSpecType
10+
FunctionLike, TypeOfAny, LiteralType, get_proper_type, TypeAliasType, ParamSpecType,
11+
TUPLE_LIKE_INSTANCE_NAMES,
1112
)
1213
import mypy.applytype
1314
import mypy.constraints
@@ -362,11 +363,7 @@ def visit_tuple_type(self, left: TupleType) -> bool:
362363
if isinstance(right, Instance):
363364
if is_named_instance(right, 'typing.Sized'):
364365
return True
365-
elif (is_named_instance(right, 'builtins.tuple') or
366-
is_named_instance(right, 'typing.Iterable') or
367-
is_named_instance(right, 'typing.Container') or
368-
is_named_instance(right, 'typing.Sequence') or
369-
is_named_instance(right, 'typing.Reversible')):
366+
elif is_named_instance(right, TUPLE_LIKE_INSTANCE_NAMES):
370367
if right.args:
371368
iter_type = right.args[0]
372369
else:
@@ -1377,11 +1374,7 @@ def visit_callable_type(self, left: CallableType) -> bool:
13771374
def visit_tuple_type(self, left: TupleType) -> bool:
13781375
right = self.right
13791376
if isinstance(right, Instance):
1380-
if (is_named_instance(right, 'builtins.tuple') or
1381-
is_named_instance(right, 'typing.Iterable') or
1382-
is_named_instance(right, 'typing.Container') or
1383-
is_named_instance(right, 'typing.Sequence') or
1384-
is_named_instance(right, 'typing.Reversible')):
1377+
if is_named_instance(right, TUPLE_LIKE_INSTANCE_NAMES):
13851378
if not right.args:
13861379
return False
13871380
iter_type = get_proper_type(right.args[0])

mypy/types.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,15 @@
117117
'typing_extensions.Annotated',
118118
)
119119

120+
# We use this constant in various places when checking `tuple` subtyping:
121+
TUPLE_LIKE_INSTANCE_NAMES: Final = (
122+
'builtins.tuple',
123+
'typing.Iterable',
124+
'typing.Container',
125+
'typing.Sequence',
126+
'typing.Reversible',
127+
)
128+
120129
# A placeholder used for Bogus[...] parameters
121130
_dummy: Final[Any] = object()
122131

@@ -2482,9 +2491,12 @@ def strip_type(typ: Type) -> ProperType:
24822491
return typ
24832492

24842493

2485-
def is_named_instance(t: Type, fullname: str) -> bool:
2494+
def is_named_instance(t: Type, fullnames: Union[str, Tuple[str, ...]]) -> bool:
2495+
if not isinstance(fullnames, tuple):
2496+
fullnames = (fullnames,)
2497+
24862498
t = get_proper_type(t)
2487-
return isinstance(t, Instance) and t.type.fullname == fullname
2499+
return isinstance(t, Instance) and t.type.fullname in fullnames
24882500

24892501

24902502
TP = TypeVar('TP', bound=Type)

0 commit comments

Comments
 (0)