Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 95 additions & 4 deletions Lib/test/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -4171,38 +4171,129 @@ class OverrideDecoratorTests(BaseTestCase):
def test_override(self):
class Base:
def normal_method(self): ...
@classmethod
def class_method_good_order(cls): ...
@classmethod
def class_method_bad_order(cls): ...
@staticmethod
def static_method_good_order(): ...
@staticmethod
def static_method_bad_order(): ...
@staticmethod
def decorator_with_slots(): ...

class Derived(Base):
@override
def normal_method(self):
return 42

@classmethod
@override
def class_method_good_order(cls):
return 42
@override
@classmethod
def class_method_bad_order(cls):
return 42

@staticmethod
@override
def static_method_good_order():
return 42

@override
@staticmethod
def static_method_bad_order():
return 42


self.assertIsSubclass(Derived, Base)
instance = Derived()
self.assertEqual(instance.normal_method(), 42)
self.assertIs(True, Derived.normal_method.__override__)
self.assertIs(True, instance.normal_method.__override__)

self.assertEqual(Derived.class_method_good_order(), 42)
self.assertIs(True, Derived.class_method_good_order.__override__)
self.assertEqual(Derived.class_method_bad_order(), 42)
self.assertIs(False, hasattr(Derived.class_method_bad_order, "__override__"))

self.assertEqual(Derived.static_method_good_order(), 42)
self.assertIs(True, Derived.static_method_good_order.__override__)
self.assertEqual(Derived.static_method_bad_order(), 42)
self.assertIs(False, hasattr(Derived.static_method_bad_order, "__override__"))

# Base object is not changed:
self.assertIs(False, hasattr(Base.normal_method, "__override__"))
self.assertIs(False, hasattr(Base.class_method_good_order, "__override__"))
self.assertIs(False, hasattr(Base.class_method_bad_order, "__override__"))
self.assertIs(False, hasattr(Base.static_method_good_order, "__override__"))
self.assertIs(False, hasattr(Base.static_method_bad_order, "__override__"))

def test_property(self):
class Base:
@property
def correct(self) -> int:
return 1
@property
def wrong(self) -> int:
return 1

class Child(Base):
@property
@override
def correct(self) -> int:
return 2
@override
@property
def wrong(self) -> int:
return 2

instance = Child()
self.assertEqual(instance.correct, 2)
self.assertTrue(Child.correct.fget.__override__)
self.assertEqual(instance.wrong, 2)
self.assertFalse(hasattr(Child.wrong, "__override__"))
self.assertFalse(hasattr(Child.wrong.fset, "__override__"))

def test_silent_failure(self):
class CustomProp:
__slots__ = ('fget',)
def __init__(self, fget):
self.fget = fget
def __get__(self, obj, objtype=None):
return self.fget(obj)

class WithOverride:
@override # must not fail on object with `__slots__`
@CustomProp
def some(self):
return 1

self.assertEqual(WithOverride.some, 1)
self.assertFalse(hasattr(WithOverride.some, "__override__"))

def test_multiple_decorators(self):
import functools

def with_wraps(f): # similar to `lru_cache` definition
@functools.wraps(f)
def wrapper(*args, **kwargs):
return f(*args, **kwargs)
return wrapper

class WithOverride:
@override
@with_wraps
def on_top(self, a: int) -> int:
return a + 1
@with_wraps
@override
def on_bottom(self, a: int) -> int:
return a + 2

instance = WithOverride()
self.assertEqual(instance.on_top(1), 2)
self.assertTrue(instance.on_top.__override__)
self.assertEqual(instance.on_bottom(1), 3)
self.assertTrue(instance.on_bottom.__override__)


class CastTests(BaseTestCase):

Expand Down