Skip to content

Commit

Permalink
Bring in protocol’s __init__ behaviour same like in python > 3.8 (#780)
Browse files Browse the repository at this point in the history
  • Loading branch information
dkraczkowski authored Apr 10, 2021
1 parent c23141f commit 6a2a490
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 7 deletions.
9 changes: 9 additions & 0 deletions typing_extensions/src_py3/test_typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1448,6 +1448,15 @@ def close(self):
self.assertIsSubclass(B, Custom)
self.assertNotIsSubclass(A, Custom)

def test_no_init_same_for_different_protocol_implementations(self):
class CustomProtocolWithoutInitA(Protocol):
pass

class CustomProtocolWithoutInitB(Protocol):
pass

self.assertEqual(CustomProtocolWithoutInitA.__init__, CustomProtocolWithoutInitB.__init__)


class TypedDictTests(BaseTestCase):

Expand Down
16 changes: 9 additions & 7 deletions typing_extensions/src_py3/typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,11 @@ def _is_callable_members_only(cls):
if hasattr(typing, 'Protocol'):
Protocol = typing.Protocol
elif HAVE_PROTOCOLS and not PEP_560:

def _no_init(self, *args, **kwargs):
if type(self)._is_protocol:
raise TypeError('Protocols cannot be instantiated')

class _ProtocolMeta(GenericMeta):
"""Internal metaclass for Protocol.
Expand Down Expand Up @@ -1241,9 +1246,6 @@ def __init__(cls, *args, **kwargs):
raise TypeError('Protocols can only inherit from other'
' protocols, got %r' % base)

def _no_init(self, *args, **kwargs):
if type(self)._is_protocol:
raise TypeError('Protocols cannot be instantiated')
cls.__init__ = _no_init

def _proto_hook(other):
Expand Down Expand Up @@ -1398,6 +1400,10 @@ def __new__(cls, *args, **kwds):
elif PEP_560:
from typing import _type_check, _GenericAlias, _collect_type_vars # noqa

def _no_init(self, *args, **kwargs):
if type(self)._is_protocol:
raise TypeError('Protocols cannot be instantiated')

class _ProtocolMeta(abc.ABCMeta):
# This metaclass is a bit unfortunate and exists only because of the lack
# of __instancehook__.
Expand Down Expand Up @@ -1574,10 +1580,6 @@ def _proto_hook(other):
isinstance(base, _ProtocolMeta) and base._is_protocol):
raise TypeError('Protocols can only inherit from other'
' protocols, got %r' % base)

def _no_init(self, *args, **kwargs):
if type(self)._is_protocol:
raise TypeError('Protocols cannot be instantiated')
cls.__init__ = _no_init


Expand Down

0 comments on commit 6a2a490

Please sign in to comment.