8000 bpo-37058: PEP 544: Add Protocol to typing module by ilevkivskyi · Pull Request #13585 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-37058: PEP 544: Add Protocol to typing module #13585

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
May 28, 2019
Prev Previous commit
Next Next commit
Allow sub-protocols of protocols in collections.abc
  • Loading branch information
ilevkivskyi committed May 26, 2019
commit a5409029dafaaa9d052c2a2bb8f60b3fa59ea6a3
14 changes: 14 additions & 0 deletions Lib/test/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,20 @@ class C2(C1):
c = C2()
self.assertIsInstance(c, C1)

def test_collections_protocols_allowed(self):
@runtime_checkable
class Custom(collections.abc.Iterable, Protocol):
def close(self): ...

class A: pass
class B:
def __iter__(self):
return []
def close(self):
return 0

self.assertIsSubclass(B, Custom)
self.assertNotIsSubclass(A, Custom)

class GenericTests(BaseTestCase):

Expand Down
9 changes: 5 additions & 4 deletions Lib/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -983,10 +983,10 @@ def _allow_reckless_class_cheks():
return True


_PROTOCOL_WHITELIST = ['Callable', 'Awaitable',
'Iterable', 'Iterator', 'AsyncIterable', 'AsyncIterator',
'Hashable', 'Sized', 'Container', 'Collection', 'Reversible',
'ContextManager', 'AsyncContextManager']
_PROTO_WHITELIST = ['Callable', 'Awaitable',
'Iterable', 'Iterator', 'AsyncIterable', 'AsyncIterator',
'Hashable', 'Sized', 'Container', 'Collection', 'Reversible',
'ContextManager', 'AsyncContextManager']


class _ProtocolMeta(ABCMeta):
Expand Down Expand Up @@ -1097,6 +1097,7 @@ 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
issubclass(base, Generic) and base._is_protocol):
raise TypeError('Protocols can only inherit from other'
' protocols, got %r' % base)
Expand Down
0