mirror of https://github.com/python/cpython
bpo-44807: Allow Protocol classes to define __init__ (GH-31628)
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
This commit is contained in:
parent
b0b836b20c
commit
5f2abae61e
|
@ -1598,6 +1598,32 @@ class ProtocolTests(BaseTestCase):
|
|||
with self.assertRaises(TypeError):
|
||||
CG[int](42)
|
||||
|
||||
def test_protocol_defining_init_does_not_get_overridden(self):
|
||||
# check that P.__init__ doesn't get clobbered
|
||||
# see https://bugs.python.org/issue44807
|
||||
|
||||
class P(Protocol):
|
||||
x: int
|
||||
def __init__(self, x: int) -> None:
|
||||
self.x = x
|
||||
class C: pass
|
||||
|
||||
c = C()
|
||||
P.__init__(c, 1)
|
||||
self.assertEqual(c.x, 1)
|
||||
|
||||
def test_concrete_class_inheriting_init_from_protocol(self):
|
||||
class P(Protocol):
|
||||
x: int
|
||||
def __init__(self, x: int) -> None:
|
||||
self.x = x
|
||||
|
||||
class C(P): pass
|
||||
|
||||
c = C(1)
|
||||
self.assertIsInstance(c, C)
|
||||
self.assertEqual(c.x, 1)
|
||||
|
||||
def test_cannot_instantiate_abstract(self):
|
||||
@runtime_checkable
|
||||
class P(Protocol):
|
||||
|
|
|
@ -1997,7 +1997,8 @@ class Protocol(Generic, metaclass=_ProtocolMeta):
|
|||
issubclass(base, Generic) and base._is_protocol):
|
||||
raise TypeError('Protocols can only inherit from other'
|
||||
' protocols, got %r' % base)
|
||||
cls.__init__ = _no_init_or_replace_init
|
||||
if cls.__init__ is Protocol.__init__:
|
||||
cls.__init__ = _no_init_or_replace_init
|
||||
|
||||
|
||||
class _AnnotatedAlias(_GenericAlias, _root=True):
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
:class:`typing.Protocol` no longer silently replaces :meth:`__init__` methods defined on subclasses. Patch by Adrian Garcia Badaracco.
|
Loading…
Reference in New Issue