bpo-38008: Move builtin protocol whitelist to mapping instead of list (GH-15647)

Fixes https://bugs.python.org/issue38008
This commit is contained in:
Divij Rajkumar 2019-09-12 11:13:51 +01:00 committed by Ivan Levkivskyi
parent ea683deccc
commit 692a0dc915
3 changed files with 20 additions and 5 deletions

View File

@ -1381,6 +1381,14 @@ class ProtocolTests(BaseTestCase):
self.assertIsSubclass(B, Custom)
self.assertNotIsSubclass(A, Custom)
def test_builtin_protocol_whitelist(self):
with self.assertRaises(TypeError):
class CustomProtocol(TestCase, Protocol):
pass
class CustomContextManager(typing.ContextManager, Protocol):
pass
class GenericTests(BaseTestCase):
def test_basics(self):

View File

@ -989,10 +989,13 @@ def _allow_reckless_class_cheks():
return True
_PROTO_WHITELIST = ['Callable', 'Awaitable',
'Iterable', 'Iterator', 'AsyncIterable', 'AsyncIterator',
'Hashable', 'Sized', 'Container', 'Collection', 'Reversible',
'ContextManager', 'AsyncContextManager']
_PROTO_WHITELIST = {
'collections.abc': [
'Callable', 'Awaitable', 'Iterable', 'Iterator', 'AsyncIterable',
'Hashable', 'Sized', 'Container', 'Collection', 'Reversible',
],
'contextlib': ['AbstractContextManager', 'AbstractAsyncContextManager'],
}
class _ProtocolMeta(ABCMeta):
@ -1105,7 +1108,8 @@ class Protocol(Generic, metaclass=_ProtocolMeta):
# ... otherwise check consistency of bases, and prohibit instantiation.
for base in cls.__bases__:
if not (base in (object, Generic) or
base.__module__ == 'collections.abc' and base.__name__ in _PROTO_WHITELIST or
base.__module__ in _PROTO_WHITELIST and
base.__name__ in _PROTO_WHITELIST[base.__module__] or
issubclass(base, Generic) and base._is_protocol):
raise TypeError('Protocols can only inherit from other'
' protocols, got %r' % base)

View File

@ -0,0 +1,3 @@
Fix parent class check in protocols to correctly identify the module that
provides a builtin protocol, instead of assuming they all come from the
:mod:`collections.abc` module