summaryrefslogtreecommitdiff
path: root/Lib/test/test_typing.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_typing.py')
-rw-r--r--Lib/test/test_typing.py76
1 files changed, 76 insertions, 0 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 045f2a3b4d..bf038bf143 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -2695,6 +2695,82 @@ class ProtocolTests(BaseTestCase):
with self.assertRaises(TypeError):
issubclass(D, PNonCall)
+ def test_no_weird_caching_with_issubclass_after_isinstance(self):
+ @runtime_checkable
+ class Spam(Protocol):
+ x: int
+
+ class Eggs:
+ def __init__(self) -> None:
+ self.x = 42
+
+ self.assertIsInstance(Eggs(), Spam)
+
+ # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta,
+ # TypeError wouldn't be raised here,
+ # as the cached result of the isinstance() check immediately above
+ # would mean the issubclass() call would short-circuit
+ # before we got to the "raise TypeError" line
+ with self.assertRaises(TypeError):
+ issubclass(Eggs, Spam)
+
+ def test_no_weird_caching_with_issubclass_after_isinstance_2(self):
+ @runtime_checkable
+ class Spam(Protocol):
+ x: int
+
+ class Eggs: ...
+
+ self.assertNotIsInstance(Eggs(), Spam)
+
+ # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta,
+ # TypeError wouldn't be raised here,
+ # as the cached result of the isinstance() check immediately above
+ # would mean the issubclass() call would short-circuit
+ # before we got to the "raise TypeError" line
+ with self.assertRaises(TypeError):
+ issubclass(Eggs, Spam)
+
+ def test_no_weird_caching_with_issubclass_after_isinstance_3(self):
+ @runtime_checkable
+ class Spam(Protocol):
+ x: int
+
+ class Eggs:
+ def __getattr__(self, attr):
+ if attr == "x":
+ return 42
+ raise AttributeError(attr)
+
+ self.assertNotIsInstance(Eggs(), Spam)
+
+ # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta,
+ # TypeError wouldn't be raised here,
+ # as the cached result of the isinstance() check immediately above
+ # would mean the issubclass() call would short-circuit
+ # before we got to the "raise TypeError" line
+ with self.assertRaises(TypeError):
+ issubclass(Eggs, Spam)
+
+ def test_no_weird_caching_with_issubclass_after_isinstance_pep695(self):
+ @runtime_checkable
+ class Spam[T](Protocol):
+ x: T
+
+ class Eggs[T]:
+ def __init__(self, x: T) -> None:
+ self.x = x
+
+ self.assertIsInstance(Eggs(42), Spam)
+
+ # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta,
+ # TypeError wouldn't be raised here,
+ # as the cached result of the isinstance() check immediately above
+ # would mean the issubclass() call would short-circuit
+ # before we got to the "raise TypeError" line
+ with self.assertRaises(TypeError):
+ issubclass(Eggs, Spam)
+
def test_protocols_isinstance(self):
T = TypeVar('T')