[Python-checkins] bpo-38008: Move builtin protocol whitelist to mapping instead of list (GH-15647)
Miss Islington (bot)
webhook-mailer at python.org
Thu Sep 12 06:32:41 EDT 2019
https://github.com/python/cpython/commit/52baf90a74f3a4573f4266bb4ca8569534db42a9
commit: 52baf90a74f3a4573f4266bb4ca8569534db42a9
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2019-09-12T03:32:36-07:00
summary:
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 at gmail.com>
files:
A Misc/NEWS.d/next/Library/2019-09-12-10-47-34.bpo-38008.sH74Iy.rst
M Lib/test/test_typing.py
M Lib/typing.py
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index ba0800fae90e..3402996b2d2e 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -1381,6 +1381,14 @@ def close(self):
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 5f1a0ad3d637..7b07112c3abf 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 @@ def _proto_hook(other):
# ... 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 000000000000..f696707eadf7
--- /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
More information about the Python-checkins
mailing list