File isinstance_w_gen_prot_subcls.patch of Package python-typing.15192
From a75292e5aa5aafb4b25207c2cc2a9d4647754bd0 Mon Sep 17 00:00:00 2001
From: Ivan Levkivskyi <ilevkivskyi@dropbox.com>
Date: Thu, 22 Aug 2019 13:15:51 +0100
Subject: [PATCH 1/2] Fix isinstance() with generic protocol subclasses after
subscripting
---
python2/test_typing.py | 21 +++++++++++++++++++++
python2/typing.py | 19 +++++++++++--------
2 files changed, 32 insertions(+), 8 deletions(-)
--- a/python2/test_typing.py
+++ b/python2/test_typing.py
@@ -749,6 +749,27 @@ class ProtocolTests(BaseTestCase):
self.assertIsInstance(C(1), P)
self.assertIsInstance(C(1), PG)
+ def test_protocol_checks_after_subscript(self):
+ class P(Protocol[T]): pass
+ class C(P[T]): pass
+ class Old1: pass
+ class New1(object): pass
+ class Old2: pass
+ class New2(object): pass
+ CA = C[Any] # noqa
+
+ self.assertNotIsInstance(Old1(), C)
+ self.assertNotIsInstance(New1(), C)
+ self.assertNotIsSubclass(Old2, C)
+ self.assertNotIsSubclass(New2, C)
+
+ class D1(C[Any]): pass
+ class D2(C[Any]): pass
+ CI = C[int] # noqa
+
+ self.assertIsInstance(D1(), C)
+ self.assertIsSubclass(D2, C)
+
def test_protocols_support_register(self):
@runtime_checkable
class P(Protocol):
--- a/python2/typing.py
+++ b/python2/typing.py
@@ -1393,14 +1393,17 @@ class GenericMeta(TypingMeta, abc.ABCMet
def __subclasscheck__(self, cls):
if self.__origin__ is not None:
- # This should only be modules within the standard
- # library. singledispatch is the only exception, because
- # it's a Python 2 backport of functools.singledispatch.
- if sys._getframe(1).f_globals['__name__'] not in ['abc', 'functools',
- 'singledispatch']:
- raise TypeError("Parameterized generics cannot be used with class "
- "or instance checks")
- return False
+ # These should only be modules within the standard library.
+ # singledispatch is an exception, because it's a Python 2 backport
+ # of functools.singledispatch.
+ whitelist = ['abc', 'functools', 'singledispatch']
+ if (sys._getframe(1).f_globals['__name__'] in whitelist or
+ # The second frame is needed for the case where we came
+ # from _ProtocolMeta.__subclasscheck__.
+ sys._getframe(2).f_globals['__name__'] in whitelist):
+ return False
+ raise TypeError("Parameterized generics cannot be used with class "
+ "or instance checks")
if self is Generic:
raise TypeError("Class %r cannot be used with class "
"or instance checks" % self)