summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2023-06-07 22:54:42 (GMT)
committerGitHub <noreply@github.com>2023-06-07 22:54:42 (GMT)
commit4b2263e4bf4952cf9671298f5cde2bc92333223b (patch)
treea0e839396b458422d34ef42530b35f8d2e894bbd
parent3d4a786b9b6382efa0dbe6f28d34b26426bb4165 (diff)
downloadcpython-4b2263e4bf4952cf9671298f5cde2bc92333223b.zip
cpython-4b2263e4bf4952cf9671298f5cde2bc92333223b.tar.gz
cpython-4b2263e4bf4952cf9671298f5cde2bc92333223b.tar.bz2
[3.12] gh-103171: Forward-port new tests for runtime-checkable protocols decorated with `@final` (GH-105473) (#105474)
Forward-port of the tests that were added to the 3.11 branch in GH-105445 (cherry picked from commit f5df347fcf5fe029edbe6bf274da0f4880401852) Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
-rw-r--r--Lib/test/test_typing.py65
1 files changed, 65 insertions, 0 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index ef1db06..7448089 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -3800,6 +3800,71 @@ class ProtocolTests(BaseTestCase):
# before any isinstance() checks against Sized
self.assertNotIsInstance(1, typing.Sized)
+ 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):