@@ -2189,6 +2189,10 @@ def configure_base_classes(
2189
2189
if not self .verify_base_classes (defn ):
2190
2190
self .set_dummy_mro (defn .info )
2191
2191
return
2192
+ if not self .verify_duplicate_base_classes (defn ):
2193
+ # We don't want to block the typechecking process,
2194
+ # so, we just insert `Any` as the base class and show an error.
2195
+ self .set_any_mro (defn .info )
2192
2196
self .calculate_class_mro (defn , self .object_type )
2193
2197
2194
2198
def configure_tuple_base_class (self , defn : ClassDef , base : TupleType ) -> Instance :
@@ -2218,6 +2222,11 @@ def set_dummy_mro(self, info: TypeInfo) -> None:
2218
2222
info .mro = [info , self .object_type ().type ]
2219
2223
info .bad_mro = True
2220
2224
2225
+ def set_any_mro (self , info : TypeInfo ) -> None :
2226
+ # Give it an MRO consisting direct `Any` subclass.
2227
+ info .fallback_to_any = True
2228
+ info .mro = [info , self .object_type ().type ]
2229
+
2221
2230
def calculate_class_mro (
2222
2231
self , defn : ClassDef , obj_type : Callable [[], Instance ] | None = None
2223
2232
) -> None :
@@ -2298,12 +2307,14 @@ def verify_base_classes(self, defn: ClassDef) -> bool:
2298
2307
if self .is_base_class (info , baseinfo ):
2299
2308
self .fail ("Cycle in inheritance hierarchy" , defn )
2300
2309
cycle = True
2301
- dup = find_duplicate (info .direct_base_classes ())
2302
- if dup :
2303
- self .fail (f'Duplicate base class "{ dup .name } "' , defn , blocker = True )
2304
- return False
2305
2310
return not cycle
2306
2311
2312
+ def verify_duplicate_base_classes (self , defn : ClassDef ) -> bool :
2313
+ dup = find_duplicate (defn .info .direct_base_classes ())
2314
+ if dup :
2315
+ self .fail (f'Duplicate base class "{ dup .name } "' , defn )
2316
+ return not dup
2317
+
2307
2318
def is_base_class (self , t : TypeInfo , s : TypeInfo ) -> bool :
2308
2319
"""Determine if t is a base class of s (but do not use mro)."""
2309
2320
# Search the base class graph for t, starting from s.
0 commit comments