Skip to content
Merged
Show file tree
Hide file tree
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
30 changes: 26 additions & 4 deletions src/test_typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,16 +164,38 @@ def test_exception(self):
class OverrideTests(BaseTestCase):
def test_override(self):
class Base:
def foo(self): ...
def normal_method(self): ...
@staticmethod
def static_method_good_order(): ...
@staticmethod
def static_method_bad_order(): ...
@staticmethod
def decorator_with_slots(): ...

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

@staticmethod
@override
def static_method_good_order():
return 42

@override
@staticmethod
def static_method_bad_order():
return 42


self.assertIsSubclass(Derived, Base)
self.assertEqual(Derived().foo(), 42)
self.assertEqual(dir(Base.foo), dir(Derived.foo))
instance = Derived()
self.assertEqual(instance.normal_method(), 42)
self.assertIs(True, instance.normal_method.__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__"))


class AnyTests(BaseTestCase):
Expand Down
11 changes: 11 additions & 0 deletions src/typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2102,9 +2102,20 @@ def method(self) -> None:
This helps prevent bugs that may occur when a base class is changed
without an equivalent change to a child class.

There is no runtime checking of these properties. The decorator
sets the ``__override__`` attribute to ``True`` on the decorated object
to allow runtime introspection.

See PEP 698 for details.

"""
try:
__arg.__override__ = True
except (AttributeError, TypeError):
# Skip the attribute silently if it is not writable.
# AttributeError happens if the object has __slots__ or a
# read-only property, TypeError if it's a builtin class.
pass
return __arg


Expand Down