@@ -4171,38 +4171,129 @@ class OverrideDecoratorTests(BaseTestCase):
41714171 def test_override (self ):
41724172 class Base :
41734173 def normal_method (self ): ...
4174+ @classmethod
4175+ def class_method_good_order (cls ): ...
4176+ @classmethod
4177+ def class_method_bad_order (cls ): ...
41744178 @staticmethod
41754179 def static_method_good_order (): ...
41764180 @staticmethod
41774181 def static_method_bad_order (): ...
4178- @staticmethod
4179- def decorator_with_slots (): ...
41804182
41814183 class Derived (Base ):
41824184 @override
41834185 def normal_method (self ):
41844186 return 42
41854187
4188+ @classmethod
4189+ @override
4190+ def class_method_good_order (cls ):
4191+ return 42
4192+ @override
4193+ @classmethod
4194+ def class_method_bad_order (cls ):
4195+ return 42
4196+
41864197 @staticmethod
41874198 @override
41884199 def static_method_good_order ():
41894200 return 42
4190-
41914201 @override
41924202 @staticmethod
41934203 def static_method_bad_order ():
41944204 return 42
41954205
4196-
41974206 self .assertIsSubclass (Derived , Base )
41984207 instance = Derived ()
41994208 self .assertEqual (instance .normal_method (), 42 )
4209+ self .assertIs (True , Derived .normal_method .__override__ )
42004210 self .assertIs (True , instance .normal_method .__override__ )
4211+
4212+ self .assertEqual (Derived .class_method_good_order (), 42 )
4213+ self .assertIs (True , Derived .class_method_good_order .__override__ )
4214+ self .assertEqual (Derived .class_method_bad_order (), 42 )
4215+ self .assertIs (False , hasattr (Derived .class_method_bad_order , "__override__" ))
4216+
42014217 self .assertEqual (Derived .static_method_good_order (), 42 )
42024218 self .assertIs (True , Derived .static_method_good_order .__override__ )
42034219 self .assertEqual (Derived .static_method_bad_order (), 42 )
42044220 self .assertIs (False , hasattr (Derived .static_method_bad_order , "__override__" ))
42054221
4222+ # Base object is not changed:
4223+ self .assertIs (False , hasattr (Base .normal_method , "__override__" ))
4224+ self .assertIs (False , hasattr (Base .class_method_good_order , "__override__" ))
4225+ self .assertIs (False , hasattr (Base .class_method_bad_order , "__override__" ))
4226+ self .assertIs (False , hasattr (Base .static_method_good_order , "__override__" ))
4227+ self .assertIs (False , hasattr (Base .static_method_bad_order , "__override__" ))
4228+
4229+ def test_property (self ):
4230+ class Base :
4231+ @property
4232+ def correct (self ) -> int :
4233+ return 1
4234+ @property
4235+ def wrong (self ) -> int :
4236+ return 1
4237+
4238+ class Child (Base ):
4239+ @property
4240+ @override
4241+ def correct (self ) -> int :
4242+ return 2
4243+ @override
4244+ @property
4245+ def wrong (self ) -> int :
4246+ return 2
4247+
4248+ instance = Child ()
4249+ self .assertEqual (instance .correct , 2 )
4250+ self .assertTrue (Child .correct .fget .__override__ )
4251+ self .assertEqual (instance .wrong , 2 )
4252+ self .assertFalse (hasattr (Child .wrong , "__override__" ))
4253+ self .assertFalse (hasattr (Child .wrong .fset , "__override__" ))
4254+
4255+ def test_silent_failure (self ):
4256+ class CustomProp :
4257+ __slots__ = ('fget' ,)
4258+ def __init__ (self , fget ):
4259+ self .fget = fget
4260+ def __get__ (self , obj , objtype = None ):
4261+ return self .fget (obj )
4262+
4263+ class WithOverride :
4264+ @override # must not fail on object with `__slots__`
4265+ @CustomProp
4266+ def some (self ):
4267+ return 1
4268+
4269+ self .assertEqual (WithOverride .some , 1 )
4270+ self .assertFalse (hasattr (WithOverride .some , "__override__" ))
4271+
4272+ def test_multiple_decorators (self ):
4273+ import functools
4274+
4275+ def with_wraps (f ): # similar to `lru_cache` definition
4276+ @functools .wraps (f )
4277+ def wrapper (* args , ** kwargs ):
4278+ return f (* args , ** kwargs )
4279+ return wrapper
4280+
4281+ class WithOverride :
4282+ @override
4283+ @with_wraps
4284+ def on_top (self , a : int ) -> int :
4285+ return a + 1
4286+ @with_wraps
4287+ @override
4288+ def on_bottom (self , a : int ) -> int :
4289+ return a + 2
4290+
4291+ instance = WithOverride ()
4292+ self .assertEqual (instance .on_top (1 ), 2 )
4293+ self .assertTrue (instance .on_top .__override__ )
4294+ self .assertEqual (instance .on_bottom (1 ), 3 )
4295+ self .assertTrue (instance .on_bottom .__override__ )
4296+
42064297
42074298class CastTests (BaseTestCase ):
42084299
0 commit comments