@@ -643,15 +643,17 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
643
643
if defn .impl :
644
644
defn .impl .accept (self )
645
645
if defn .info :
646
- found_base_method = self .check_method_override (defn )
647
- if defn .is_explicit_override and found_base_method is False :
646
+ method_base_class = self .check_method_override (defn )
647
+ if defn .is_explicit_override and not method_base_class :
648
648
self .msg .no_overridable_method (defn .name , defn )
649
649
elif (
650
- found_base_method
650
+ method_base_class
651
651
and self .options .strict_override_decorator
652
652
and not defn .is_explicit_override
653
653
):
654
- self .msg .override_decorator_missing (defn .name , defn .impl or defn )
654
+ self .msg .override_decorator_missing (
655
+ defn .name , method_base_class .fullname , defn .impl or defn
656
+ )
655
657
self .check_inplace_operator_method (defn )
656
658
if not defn .is_property :
657
659
self .check_overlapping_overloads (defn )
@@ -978,13 +980,15 @@ def _visit_func_def(self, defn: FuncDef) -> None:
978
980
# overload, the legality of the override has already
979
981
# been typechecked, and decorated methods will be
980
982
# checked when the decorator is.
981
- found_base_method = self .check_method_override (defn )
983
+ method_base_class = self .check_method_override (defn )
982
984
if (
983
- found_base_method
985
+ method_base_class
984
986
and self .options .strict_override_decorator
985
987
and defn .name not in ("__init__" , "__new__" )
986
988
):
987
- self .msg .override_decorator_missing (defn .name , defn )
989
+ self .msg .override_decorator_missing (
990
+ defn .name , method_base_class .fullname , defn
991
+ )
988
992
self .check_inplace_operator_method (defn )
989
993
if defn .original_def :
990
994
# Override previous definition.
@@ -1826,23 +1830,26 @@ def expand_typevars(
1826
1830
else :
1827
1831
return [(defn , typ )]
1828
1832
1829
- def check_method_override (self , defn : FuncDef | OverloadedFuncDef | Decorator ) -> bool | None :
1833
+ def check_method_override (
1834
+ self , defn : FuncDef | OverloadedFuncDef | Decorator
1835
+ ) -> TypeInfo | None :
1830
1836
"""Check if function definition is compatible with base classes.
1831
1837
1832
1838
This may defer the method if a signature is not available in at least one base class.
1833
1839
Return ``None`` if that happens.
1834
1840
1841
+ Return the first base class if an attribute with the method name was found within it.
1835
1842
Return ``True`` if an attribute with the method name was found in the base class.
1836
1843
"""
1837
1844
# Check against definitions in base classes.
1838
- found_base_method = False
1839
1845
for base in defn .info .mro [1 :]:
1840
1846
result = self .check_method_or_accessor_override_for_base (defn , base )
1841
1847
if result is None :
1842
1848
# Node was deferred, we will have another attempt later.
1843
1849
return None
1844
- found_base_method |= result
1845
- return found_base_method
1850
+ if result :
1851
+ return base
1852
+ return None
1846
1853
1847
1854
def check_method_or_accessor_override_for_base (
1848
1855
self , defn : FuncDef | OverloadedFuncDef | Decorator , base : TypeInfo
@@ -4752,15 +4759,17 @@ def visit_decorator(self, e: Decorator) -> None:
4752
4759
self .check_incompatible_property_override (e )
4753
4760
# For overloaded functions we already checked override for overload as a whole.
4754
4761
if e .func .info and not e .func .is_dynamic () and not e .is_overload :
4755
- found_base_method = self .check_method_override (e )
4756
- if e .func .is_explicit_override and found_base_method is False :
4762
+ method_base_class = self .check_method_override (e )
4763
+ if e .func .is_explicit_override and not method_base_class :
4757
4764
self .msg .no_overridable_method (e .func .name , e .func )
4758
4765
elif (
4759
- found_base_method
4766
+ method_base_class
4760
4767
and self .options .strict_override_decorator
4761
4768
and not e .func .is_explicit_override
4762
4769
):
4763
- self .msg .override_decorator_missing (e .func .name , e .func )
4770
+ self .msg .override_decorator_missing (
4771
+ e .func .name , method_base_class .fullname , e .func
4772
+ )
4764
4773
4765
4774
if e .func .info and e .func .name in ("__init__" , "__new__" ):
4766
4775
if e .type and not isinstance (get_proper_type (e .type ), (FunctionLike , AnyType )):
0 commit comments