@@ -90,7 +90,6 @@ def __init__(
9090 ignore_promotions : bool = False ,
9191 ignore_uninhabited : bool = False ,
9292 # Proper subtype flags
93- erase_instances : bool = False ,
9493 keep_erased_types : bool = False ,
9594 options : Options | None = None ,
9695 ) -> None :
@@ -99,7 +98,6 @@ def __init__(
9998 self .ignore_declared_variance = ignore_declared_variance
10099 self .ignore_promotions = ignore_promotions
101100 self .ignore_uninhabited = ignore_uninhabited
102- self .erase_instances = erase_instances
103101 self .keep_erased_types = keep_erased_types
104102 self .options = options
105103
@@ -109,7 +107,7 @@ def check_context(self, proper_subtype: bool) -> None:
109107 if proper_subtype :
110108 assert not self .ignore_pos_arg_names and not self .ignore_declared_variance
111109 else :
112- assert not self .erase_instances and not self . keep_erased_types
110+ assert not self .keep_erased_types
113111
114112
115113def is_subtype (
@@ -187,34 +185,25 @@ def is_proper_subtype(
187185 subtype_context : SubtypeContext | None = None ,
188186 ignore_promotions : bool = False ,
189187 ignore_uninhabited : bool = False ,
190- erase_instances : bool = False ,
191188 keep_erased_types : bool = False ,
192189) -> bool :
193190 """Is left a proper subtype of right?
194191
195192 For proper subtypes, there's no need to rely on compatibility due to
196193 Any types. Every usable type is a proper subtype of itself.
197194
198- If erase_instances is True, erase left instance *after* mapping it to supertype
199- (this is useful for runtime isinstance() checks). If keep_erased_types is True,
200- do not consider ErasedType a subtype of all types (used by type inference against unions).
195+ If keep_erased_types is True, do not consider ErasedType a subtype
196+ of all types (used by type inference against unions).
201197 """
202198 if subtype_context is None :
203199 subtype_context = SubtypeContext (
204200 ignore_promotions = ignore_promotions ,
205201 ignore_uninhabited = ignore_uninhabited ,
206- erase_instances = erase_instances ,
207202 keep_erased_types = keep_erased_types ,
208203 )
209204 else :
210205 assert not any (
211- {
212- ignore_promotions ,
213- ignore_uninhabited ,
214- erase_instances ,
215- keep_erased_types ,
216- ignore_uninhabited ,
217- }
206+ {ignore_promotions , ignore_uninhabited , keep_erased_types , ignore_uninhabited }
218207 ), "Don't pass both context and individual flags"
219208 if type_state .is_assumed_proper_subtype (left , right ):
220209 return True
@@ -405,7 +394,6 @@ def build_subtype_kind(subtype_context: SubtypeContext, proper_subtype: bool) ->
405394 subtype_context .ignore_pos_arg_names ,
406395 subtype_context .ignore_declared_variance ,
407396 subtype_context .ignore_promotions ,
408- subtype_context .erase_instances ,
409397 subtype_context .keep_erased_types ,
410398 )
411399
@@ -533,10 +521,6 @@ def visit_instance(self, left: Instance) -> bool:
533521 ) and not self .subtype_context .ignore_declared_variance :
534522 # Map left type to corresponding right instances.
535523 t = map_instance_to_supertype (left , right .type )
536- if self .subtype_context .erase_instances :
537- erased = erase_type (t )
538- assert isinstance (erased , Instance )
539- t = erased
540524 nominal = True
541525 if right .type .has_type_var_tuple_type :
542526 # For variadic instances we simply find the correct type argument mappings,
@@ -1947,56 +1931,52 @@ def restrict_subtype_away(t: Type, s: Type) -> Type:
19471931def covers_type (item : Type , supertype : Type ) -> bool :
19481932 """Returns if item is covered by supertype.
19491933
1950- Assumes that item is not a Union type.
19511934 Any types (or fallbacks to any) should never cover or be covered.
1952- Examples:
19531935
1954- int covered by int
1955- List[int] covered by List[Any]
1956- A covered by Union[A, Any]
1957- Any NOT covered by int
1958- int NOT covered by Any
1936+ Assumes that item is not a Union type.
1937+
1938+ Examples:
1939+ int covered by int
1940+ List[int] covered by List[Any]
1941+ A covered by Union[A, Any]
1942+ Any NOT covered by int
1943+ int NOT covered by Any
19591944 """
19601945 item = get_proper_type (item )
19611946 supertype = get_proper_type (supertype )
19621947
1963- if isinstance (item , UnionType ):
1964- return False
1948+ assert not isinstance (item , UnionType )
19651949
19661950 # Handle possible Any types that should not be covered:
1967- if isinstance (item , AnyType ):
1968- return False
1969- if isinstance (supertype , AnyType ):
1951+ if isinstance (item , AnyType ) or isinstance (supertype , AnyType ):
19701952 return False
1971- if (isinstance (item , Instance ) and item .type .fallback_to_any ) or (
1953+ elif (isinstance (item , Instance ) and item .type .fallback_to_any ) or (
19721954 isinstance (supertype , Instance ) and supertype .type .fallback_to_any
19731955 ):
19741956 return is_same_type (item , supertype )
19751957
19761958 if isinstance (supertype , UnionType ):
1977- return any (covers_type (item , t ) for t in supertype .items )
1978-
1979- if is_subtype (item , supertype , ignore_promotions = True ):
1980- return True
1981-
1982- if isinstance (supertype , Instance ):
1959+ # Special case that cannot be handled by is_subtype, because it would
1960+ # not ignore the Any types:
1961+ return any (covers_type (item , t ) for t in supertype .relevant_items ())
1962+ elif isinstance (supertype , Instance ):
19831963 if supertype .type .is_protocol :
19841964 # TODO: Implement more robust support for runtime isinstance() checks, see issue #3827.
1985- if is_proper_subtype (item , supertype , ignore_promotions = True ):
1965+ if is_proper_subtype (item , erase_type ( supertype ) , ignore_promotions = True ):
19861966 return True
19871967 if isinstance (item , TypedDictType ):
19881968 # Special case useful for selecting TypedDicts from unions using isinstance(x, dict).
19891969 if supertype .type .fullname == "builtins.dict" :
19901970 return True
19911971 elif isinstance (item , TypeVarType ):
1992- if is_proper_subtype (item .upper_bound , supertype , ignore_promotions = True ):
1972+ if is_proper_subtype (item .upper_bound , erase_type ( supertype ) , ignore_promotions = True ):
19931973 return True
19941974 elif isinstance (item , Instance ) and supertype .type .fullname == "builtins.int" :
19951975 # "int" covers all native int types
19961976 if item .type .fullname in MYPYC_NATIVE_INT_NAMES :
19971977 return True
1998- # TODO: Add more special cases.
1999- return False
1978+
1979+ return is_subtype ( item , supertype , ignore_promotions = True )
20001980
20011981
20021982def is_more_precise (left : Type , right : Type , * , ignore_promotions : bool = False ) -> bool :
0 commit comments