diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 12bbf164ab1..0910fd4022e 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -45,6 +45,10 @@ class BaseTestCase(TestCase): message += ' : %s' % msg raise self.failureException(message) + def clear_caches(self): + for f in typing._cleanups: + f() + class Employee: pass @@ -509,6 +513,13 @@ class ProtocolTests(BaseTestCase): def test_protocol_instance_type_error(self): with self.assertRaises(TypeError): isinstance(0, typing.SupportsAbs) + class C1(typing.SupportsInt): + def __int__(self) -> int: + return 42 + class C2(C1): + pass + c = C2() + self.assertIsInstance(c, C1) class GenericTests(BaseTestCase): @@ -748,8 +759,12 @@ class GenericTests(BaseTestCase): class CC: ... self.assertEqual(get_type_hints(foobar, globals(), locals()), {'x': List[List[CC]]}) T = TypeVar('T') - def barfoo(x: Tuple[T, ...]): ... - self.assertIs(get_type_hints(barfoo, globals(), locals())['x'], Tuple[T, ...]) + AT = Tuple[T, ...] + def barfoo(x: AT): ... + self.assertIs(get_type_hints(barfoo, globals(), locals())['x'], AT) + CT = Callable[..., List[T]] + def barfoo2(x: CT): ... + self.assertIs(get_type_hints(barfoo2, globals(), locals())['x'], CT) def test_extended_generic_rules_subclassing(self): class T1(Tuple[T, KT]): ... @@ -800,6 +815,8 @@ class GenericTests(BaseTestCase): def test_type_erasure_special(self): T = TypeVar('T') + # this is the only test that checks type caching + self.clear_caches() class MyTup(Tuple[T, T]): ... self.assertIs(MyTup[int]().__class__, MyTup) self.assertIs(MyTup[int]().__orig_class__, MyTup[int]) diff --git a/Lib/typing.py b/Lib/typing.py index fe22b2b5e8e..c7fe5ddb912 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1503,6 +1503,8 @@ class _ProtocolMeta(GenericMeta): """ def __instancecheck__(self, obj): + if _Protocol not in self.__bases__: + return super().__instancecheck__(obj) raise TypeError("Protocols cannot be used with isinstance().") def __subclasscheck__(self, cls):