aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Sobolev <mail@sobolevn.me>2023-03-03 06:59:05 +0300
committerGitHub <noreply@github.com>2023-03-02 19:59:05 -0800
commit12011dd8bafa6867f2b4a8a9e8e54cb0fbf006e4 (patch)
tree85b24710ee2ac23dee9d59b2e245bda42fbf4993
parentgh-102371: move _Py_Mangle from compile.c to symtable.c (#102372) (diff)
downloadcpython-12011dd8bafa6867f2b4a8a9e8e54cb0fbf006e4.tar.gz
cpython-12011dd8bafa6867f2b4a8a9e8e54cb0fbf006e4.tar.bz2
cpython-12011dd8bafa6867f2b4a8a9e8e54cb0fbf006e4.zip
gh-102324: Improve tests of `typing.override` (#102325)
Fixes #101564
-rw-r--r--Lib/test/test_typing.py99
1 files changed, 95 insertions, 4 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index d61dc6e2fbd..96496ec9279 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -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):