6
6
TupleType , TypedDictType , ErasedType , UnionType , PartialType , DeletedType ,
7
7
UninhabitedType , TypeType , TypeOfAny , Overloaded , FunctionLike , LiteralType ,
8
8
ProperType , get_proper_type , get_proper_types , TypeAliasType , TypeGuardedType ,
9
- ParamSpecType , Parameters , UnpackType , TypeVarTupleType ,
9
+ ParamSpecType , Parameters , UnpackType , TypeVarTupleType , TypeVarLikeType
10
10
)
11
11
from mypy .subtypes import is_equivalent , is_subtype , is_callable_compatible , is_proper_subtype
12
12
from mypy .erasetype import erase_type
@@ -117,8 +117,8 @@ def get_possible_variants(typ: Type) -> List[Type]:
117
117
If this function receives any other type, we return a list containing just that
118
118
original type. (E.g. pretend the type was contained within a singleton union).
119
119
120
- The only exception is regular TypeVars: we return a list containing that TypeVar's
121
- upper bound.
120
+ The only current exceptions are regular TypeVars and ParamSpecs. For these "TypeVarLike"s,
121
+ we return a list containing that TypeVarLike's upper bound.
122
122
123
123
This function is useful primarily when checking to see if two types are overlapping:
124
124
the algorithm to check if two unions are overlapping is fundamentally the same as
@@ -134,6 +134,8 @@ def get_possible_variants(typ: Type) -> List[Type]:
134
134
return typ .values
135
135
else :
136
136
return [typ .upper_bound ]
137
+ elif isinstance (typ , ParamSpecType ):
138
+ return [typ .upper_bound ]
137
139
elif isinstance (typ , UnionType ):
138
140
return list (typ .items )
139
141
elif isinstance (typ , Overloaded ):
@@ -244,36 +246,36 @@ def _is_overlapping_types(left: Type, right: Type) -> bool:
244
246
right_possible = get_possible_variants (right )
245
247
246
248
# We start by checking multi-variant types like Unions first. We also perform
247
- # the same logic if either type happens to be a TypeVar.
249
+ # the same logic if either type happens to be a TypeVar/ParamSpec/TypeVarTuple .
248
250
#
249
- # Handling the TypeVars now lets us simulate having them bind to the corresponding
251
+ # Handling the TypeVarLikes now lets us simulate having them bind to the corresponding
250
252
# type -- if we deferred these checks, the "return-early" logic of the other
251
253
# checks will prevent us from detecting certain overlaps.
252
254
#
253
- # If both types are singleton variants (and are not TypeVars ), we've hit the base case:
255
+ # If both types are singleton variants (and are not TypeVarLikes ), we've hit the base case:
254
256
# we skip these checks to avoid infinitely recursing.
255
257
256
- def is_none_typevar_overlap (t1 : Type , t2 : Type ) -> bool :
258
+ def is_none_typevarlike_overlap (t1 : Type , t2 : Type ) -> bool :
257
259
t1 , t2 = get_proper_types ((t1 , t2 ))
258
- return isinstance (t1 , NoneType ) and isinstance (t2 , TypeVarType )
260
+ return isinstance (t1 , NoneType ) and isinstance (t2 , TypeVarLikeType )
259
261
260
262
if prohibit_none_typevar_overlap :
261
- if is_none_typevar_overlap (left , right ) or is_none_typevar_overlap (right , left ):
263
+ if is_none_typevarlike_overlap (left , right ) or is_none_typevarlike_overlap (right , left ):
262
264
return False
263
265
264
266
if (len (left_possible ) > 1 or len (right_possible ) > 1
265
- or isinstance (left , TypeVarType ) or isinstance (right , TypeVarType )):
267
+ or isinstance (left , TypeVarLikeType ) or isinstance (right , TypeVarLikeType )):
266
268
for l in left_possible :
267
269
for r in right_possible :
268
270
if _is_overlapping_types (l , r ):
269
271
return True
270
272
return False
271
273
272
- # Now that we've finished handling TypeVars , we're free to end early
274
+ # Now that we've finished handling TypeVarLikes , we're free to end early
273
275
# if one one of the types is None and we're running in strict-optional mode.
274
276
# (None only overlaps with None in strict-optional mode).
275
277
#
276
- # We must perform this check after the TypeVar checks because
278
+ # We must perform this check after the TypeVarLike checks because
277
279
# a TypeVar could be bound to None, for example.
278
280
279
281
if state .strict_optional and isinstance (left , NoneType ) != isinstance (right , NoneType ):
0 commit comments