diff options
author | Nikita Sobolev <mail@sobolevn.me> | 2023-03-03 06:59:05 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-02 19:59:05 -0800 |
commit | 12011dd8bafa6867f2b4a8a9e8e54cb0fbf006e4 (patch) | |
tree | 85b24710ee2ac23dee9d59b2e245bda42fbf4993 | |
parent | gh-102371: move _Py_Mangle from compile.c to symtable.c (#102372) (diff) | |
download | cpython-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.py | 99 |
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): |