bpo-44806: Fix __init__ in subclasses of protocols (GH-27545)

Non-protocol subclasses of protocol ignore now the __init__ method
inherited from protocol base classes.
This commit is contained in:
Serhiy Storchaka 2021-08-02 19:23:22 +03:00 committed by GitHub
parent 36d952d228
commit 043cd60abe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 2 deletions

View file

@ -1381,8 +1381,7 @@ def _is_callable_members_only(cls):
def _no_init(self, *args, **kwargs):
if type(self)._is_protocol:
raise TypeError('Protocols cannot be instantiated')
raise TypeError('Protocols cannot be instantiated')
def _caller(depth=1, default='__main__'):
try:
@ -1522,6 +1521,15 @@ class Protocol(Generic, metaclass=_ProtocolMeta):
# We have nothing more to do for non-protocols...
if not cls._is_protocol:
if cls.__init__ == _no_init:
for base in cls.__mro__:
init = base.__dict__.get('__init__', _no_init)
if init != _no_init:
cls.__init__ = init
break
else:
# should not happen
cls.__init__ = object.__init__
return
# ... otherwise check consistency of bases, and prohibit instantiation.