diff options
author | Alex Waygood <Alex.Waygood@Gmail.com> | 2023-06-07 21:18:21 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-07 21:18:21 (GMT) |
commit | 18e9fd80d956fd39ded581f91a9448aeff74b913 (patch) | |
tree | c257290237ab66f8f18031dcad797897177ee6da /Lib/test/test_typing.py | |
parent | 2ffeb0ecc78499b52b8337073c70b569413295e0 (diff) | |
download | cpython-18e9fd80d956fd39ded581f91a9448aeff74b913.zip cpython-18e9fd80d956fd39ded581f91a9448aeff74b913.tar.gz cpython-18e9fd80d956fd39ded581f91a9448aeff74b913.tar.bz2 |
[3.11] gh-103171: Revert undocumented behaviour change for runtime-checkable protocols decorated with `@final` (#105445)
Diffstat (limited to 'Lib/test/test_typing.py')
-rw-r--r-- | Lib/test/test_typing.py | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 4dfe453..316b300 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -3349,6 +3349,71 @@ class ProtocolTests(BaseTestCase): Foo() # Previously triggered RecursionError + def test_empty_protocol_decorated_with_final(self): + @final + @runtime_checkable + class EmptyProtocol(Protocol): ... + + self.assertIsSubclass(object, EmptyProtocol) + self.assertIsInstance(object(), EmptyProtocol) + + def test_protocol_decorated_with_final_callable_members(self): + @final + @runtime_checkable + class ProtocolWithMethod(Protocol): + def startswith(self, string: str) -> bool: ... + + self.assertIsSubclass(str, ProtocolWithMethod) + self.assertNotIsSubclass(int, ProtocolWithMethod) + self.assertIsInstance('foo', ProtocolWithMethod) + self.assertNotIsInstance(42, ProtocolWithMethod) + + def test_protocol_decorated_with_final_noncallable_members(self): + @final + @runtime_checkable + class ProtocolWithNonCallableMember(Protocol): + x: int + + class Foo: + x = 42 + + only_callable_members_please = ( + r"Protocols with non-method members don't support issubclass()" + ) + + with self.assertRaisesRegex(TypeError, only_callable_members_please): + issubclass(Foo, ProtocolWithNonCallableMember) + + with self.assertRaisesRegex(TypeError, only_callable_members_please): + issubclass(int, ProtocolWithNonCallableMember) + + self.assertIsInstance(Foo(), ProtocolWithNonCallableMember) + self.assertNotIsInstance(42, ProtocolWithNonCallableMember) + + def test_protocol_decorated_with_final_mixed_members(self): + @final + @runtime_checkable + class ProtocolWithMixedMembers(Protocol): + x: int + def method(self) -> None: ... + + class Foo: + x = 42 + def method(self) -> None: ... + + only_callable_members_please = ( + r"Protocols with non-method members don't support issubclass()" + ) + + with self.assertRaisesRegex(TypeError, only_callable_members_please): + issubclass(Foo, ProtocolWithMixedMembers) + + with self.assertRaisesRegex(TypeError, only_callable_members_please): + issubclass(int, ProtocolWithMixedMembers) + + self.assertIsInstance(Foo(), ProtocolWithMixedMembers) + self.assertNotIsInstance(42, ProtocolWithMixedMembers) + class GenericTests(BaseTestCase): |