@@ -2216,6 +2216,9 @@ def check_method_override_for_base_with_name(
22162216 # Will always fail to typecheck below, since we know the node is a method
22172217 original_type = NoneType ()
22182218
2219+ if isinstance (original_node , Var ) and original_node .allow_incompatible_override :
2220+ return False
2221+
22192222 always_allow_covariant = False
22202223 if is_settable_property (defn ) and (
22212224 is_settable_property (original_node ) or isinstance (original_node , Var )
@@ -2239,14 +2242,6 @@ def check_method_override_for_base_with_name(
22392242 typ = get_proper_type (typ )
22402243 original_type = get_proper_type (original_type )
22412244
2242- if name == "__hash__" and isinstance (original_type , NoneType ):
2243- # Allow defining `__hash__` even if parent class was explicitly made unhashable
2244- if base .fullname == "builtins.object" :
2245- # This is only for test stubs to avoid adding object.__hash__
2246- # to all of them.
2247- return True
2248- return self .check_method_override_for_base_with_name (defn , name , base .mro [- 1 ])
2249-
22502245 if (
22512246 is_property (defn )
22522247 and isinstance (original_node , Var )
@@ -3448,13 +3443,6 @@ def check_compatibility_all_supers(self, lvalue: RefExpr, rvalue: Expression) ->
34483443 return
34493444
34503445 for base in lvalue_node .info .mro [1 :]:
3451- # The type of "__slots__" and some other attributes usually doesn't need to
3452- # be compatible with a base class. We'll still check the type of "__slots__"
3453- # against "object" as an exception.
3454- if lvalue_node .allow_incompatible_override and not (
3455- lvalue_node .name == "__slots__" and base .fullname == "builtins.object"
3456- ):
3457- continue
34583446 if (
34593447 lvalue_node .name == "__hash__"
34603448 and base .fullname == "builtins.object"
@@ -3468,6 +3456,17 @@ def check_compatibility_all_supers(self, lvalue: RefExpr, rvalue: Expression) ->
34683456 continue
34693457
34703458 base_type , base_node = self .node_type_from_base (lvalue_node .name , base , lvalue )
3459+ # The type of "__slots__" and some other attributes usually doesn't need to
3460+ # be compatible with a base class. We'll still check the type of "__slots__"
3461+ # against "object" as an exception.
3462+ if (
3463+ isinstance (base_node , Var )
3464+ and base_node .allow_incompatible_override
3465+ and not (
3466+ lvalue_node .name == "__slots__" and base .fullname == "builtins.object"
3467+ )
3468+ ):
3469+ continue
34713470 custom_setter = is_custom_settable_property (base_node )
34723471 if isinstance (base_type , PartialType ):
34733472 base_type = None
@@ -3497,7 +3496,7 @@ def check_compatibility_all_supers(self, lvalue: RefExpr, rvalue: Expression) ->
34973496 lvalue , lvalue_type , base_type , base
34983497 )
34993498 return
3500- if base is last_immediate_base and base_node . name != "__hash__" :
3499+ if base is last_immediate_base :
35013500 # At this point, the attribute was found to be compatible with all
35023501 # immediate parents.
35033502 break
@@ -3511,9 +3510,6 @@ def check_compatibility_super(
35113510 base_node : Node ,
35123511 always_allow_covariant : bool ,
35133512 ) -> bool :
3514- if base_node .name == "__hash__" and isinstance (base_type , NoneType ):
3515- # Allow defining `__hash__` even if parent class was explicitly made unhashable
3516- return True
35173513 # TODO: check __set__() type override for custom descriptors.
35183514 # TODO: for descriptors check also class object access override.
35193515 ok = self .check_subtype (
0 commit comments