Skip to content

Commit 1881ffd

Browse files
ilevkivskyigvanrossum
authored andcommitted
Fix isinstance() for Protocols (#330)
Fixes #297 This allows to use isinstance() with classes that inherit from protocols in typing.py such as SupportsInt etc.
1 parent e3aafd8 commit 1881ffd

File tree

4 files changed

+18
-1
lines changed

4 files changed

+18
-1
lines changed

python2/test_typing.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,13 @@ def test_reversible(self):
484484
def test_protocol_instance_type_error(self):
485485
with self.assertRaises(TypeError):
486486
isinstance(0, typing.SupportsAbs)
487-
487+
class C1(typing.SupportsInt):
488+
def __int__(self):
489+
return 42
490+
class C2(C1):
491+
pass
492+
c = C2()
493+
self.assertIsInstance(c, C1)
488494

489495
class GenericTests(BaseTestCase):
490496

python2/typing.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,6 +1462,8 @@ class _ProtocolMeta(GenericMeta):
14621462
"""
14631463

14641464
def __instancecheck__(self, obj):
1465+
if _Protocol not in self.__bases__:
1466+
return super(_ProtocolMeta, self).__instancecheck__(obj)
14651467
raise TypeError("Protocols cannot be used with isinstance().")
14661468

14671469
def __subclasscheck__(self, cls):

src/test_typing.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,13 @@ def test_reversible(self):
513513
def test_protocol_instance_type_error(self):
514514
with self.assertRaises(TypeError):
515515
isinstance(0, typing.SupportsAbs)
516+
class C1(typing.SupportsInt):
517+
def __int__(self) -> int:
518+
return 42
519+
class C2(C1):
520+
pass
521+
c = C2()
522+
self.assertIsInstance(c, C1)
516523

517524

518525
class GenericTests(BaseTestCase):

src/typing.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,6 +1503,8 @@ class _ProtocolMeta(GenericMeta):
15031503
"""
15041504

15051505
def __instancecheck__(self, obj):
1506+
if _Protocol not in self.__bases__:
1507+
return super().__instancecheck__(obj)
15061508
raise TypeError("Protocols cannot be used with isinstance().")
15071509

15081510
def __subclasscheck__(self, cls):

0 commit comments

Comments
 (0)