diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2019-09-12 10:32:36 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-12 10:32:36 (GMT) |
commit | 52baf90a74f3a4573f4266bb4ca8569534db42a9 (patch) | |
tree | 966b5025f9d4d37ddfbeb6b6d18e88d3c3df9ac7 | |
parent | 1e17c4d414049ad2b5b6a0a53685efc7a550c5c5 (diff) | |
download | cpython-52baf90a74f3a4573f4266bb4ca8569534db42a9.zip cpython-52baf90a74f3a4573f4266bb4ca8569534db42a9.tar.gz cpython-52baf90a74f3a4573f4266bb4ca8569534db42a9.tar.bz2 |
bpo-38008: Move builtin protocol whitelist to mapping instead of list (GH-15647)
Fixes https://bugs.python.org/issue38008
(cherry picked from commit 692a0dc91597b7fb350383b633dc4d044cbd360e)
Co-authored-by: Divij Rajkumar <drajkuma1@gmail.com>
-rw-r--r-- | Lib/test/test_typing.py | 8 | ||||
-rw-r--r-- | Lib/typing.py | 14 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2019-09-12-10-47-34.bpo-38008.sH74Iy.rst | 3 |
3 files changed, 20 insertions, 5 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index ba0800f..3402996 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -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): diff --git a/Lib/typing.py b/Lib/typing.py index 5f1a0ad..7b07112 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -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) diff --git a/Misc/NEWS.d/next/Library/2019-09-12-10-47-34.bpo-38008.sH74Iy.rst b/Misc/NEWS.d/next/Library/2019-09-12-10-47-34.bpo-38008.sH74Iy.rst new file mode 100644 index 0000000..f696707 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-09-12-10-47-34.bpo-38008.sH74Iy.rst @@ -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 |