Skip to content

Commit 4b2263e

Browse files
[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 f5df347) Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
1 parent 3d4a786 commit 4b2263e

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

Lib/test/test_typing.py

+65
Original file line numberDiff line numberDiff line change
@@ -3800,6 +3800,71 @@ class Foo(typing.Sized, Protocol): pass
38003800
# before any isinstance() checks against Sized
38013801
self.assertNotIsInstance(1, typing.Sized)
38023802

3803+
def test_empty_protocol_decorated_with_final(self):
3804+
@final
3805+
@runtime_checkable
3806+
class EmptyProtocol(Protocol): ...
3807+
3808+
self.assertIsSubclass(object, EmptyProtocol)
3809+
self.assertIsInstance(object(), EmptyProtocol)
3810+
3811+
def test_protocol_decorated_with_final_callable_members(self):
3812+
@final
3813+
@runtime_checkable
3814+
class ProtocolWithMethod(Protocol):
3815+
def startswith(self, string: str) -> bool: ...
3816+
3817+
self.assertIsSubclass(str, ProtocolWithMethod)
3818+
self.assertNotIsSubclass(int, ProtocolWithMethod)
3819+
self.assertIsInstance('foo', ProtocolWithMethod)
3820+
self.assertNotIsInstance(42, ProtocolWithMethod)
3821+
3822+
def test_protocol_decorated_with_final_noncallable_members(self):
3823+
@final
3824+
@runtime_checkable
3825+
class ProtocolWithNonCallableMember(Protocol):
3826+
x: int
3827+
3828+
class Foo:
3829+
x = 42
3830+
3831+
only_callable_members_please = (
3832+
r"Protocols with non-method members don't support issubclass()"
3833+
)
3834+
3835+
with self.assertRaisesRegex(TypeError, only_callable_members_please):
3836+
issubclass(Foo, ProtocolWithNonCallableMember)
3837+
3838+
with self.assertRaisesRegex(TypeError, only_callable_members_please):
3839+
issubclass(int, ProtocolWithNonCallableMember)
3840+
3841+
self.assertIsInstance(Foo(), ProtocolWithNonCallableMember)
3842+
self.assertNotIsInstance(42, ProtocolWithNonCallableMember)
3843+
3844+
def test_protocol_decorated_with_final_mixed_members(self):
3845+
@final
3846+
@runtime_checkable
3847+
class ProtocolWithMixedMembers(Protocol):
3848+
x: int
3849+
def method(self) -> None: ...
3850+
3851+
class Foo:
3852+
x = 42
3853+
def method(self) -> None: ...
3854+
3855+
only_callable_members_please = (
3856+
r"Protocols with non-method members don't support issubclass()"
3857+
)
3858+
3859+
with self.assertRaisesRegex(TypeError, only_callable_members_please):
3860+
issubclass(Foo, ProtocolWithMixedMembers)
3861+
3862+
with self.assertRaisesRegex(TypeError, only_callable_members_please):
3863+
issubclass(int, ProtocolWithMixedMembers)
3864+
3865+
self.assertIsInstance(Foo(), ProtocolWithMixedMembers)
3866+
self.assertNotIsInstance(42, ProtocolWithMixedMembers)
3867+
38033868

38043869
class GenericTests(BaseTestCase):
38053870

0 commit comments

Comments
 (0)