File tree Expand file tree Collapse file tree 3 files changed +32
-1
lines changed Expand file tree Collapse file tree 3 files changed +32
-1
lines changed Original file line number Diff line number Diff line change 29
29
` typing_extensions ` may no longer be considered instances of that protocol
30
30
using the new release, and vice versa. Most users are unlikely to be affected
31
31
by this change. Patch by Alex Waygood.
32
+ - Backport the ability to define ` __init__ ` methods on Protocol classes, a
33
+ change made in Python 3.11 (originally implemented in
34
+ https://github.com/python/cpython/pull/31628 by Adrian Garcia Badaracco).
35
+ Patch by Alex Waygood.
32
36
- Speedup ` isinstance(3, typing_extensions.SupportsIndex) ` by >10x on Python
33
37
<3.12. Patch by Alex Waygood.
34
38
Original file line number Diff line number Diff line change @@ -1454,6 +1454,32 @@ class PG(Protocol[T]): pass
1454
1454
class CG (PG [T ]): pass
1455
1455
self .assertIsInstance (CG [int ](), CG )
1456
1456
1457
+ def test_protocol_defining_init_does_not_get_overridden (self ):
1458
+ # check that P.__init__ doesn't get clobbered
1459
+ # see https://bugs.python.org/issue44807
1460
+
1461
+ class P (Protocol ):
1462
+ x : int
1463
+ def __init__ (self , x : int ) -> None :
1464
+ self .x = x
1465
+ class C : pass
1466
+
1467
+ c = C ()
1468
+ P .__init__ (c , 1 )
1469
+ self .assertEqual (c .x , 1 )
1470
+
1471
+ def test_concrete_class_inheriting_init_from_protocol (self ):
1472
+ class P (Protocol ):
1473
+ x : int
1474
+ def __init__ (self , x : int ) -> None :
1475
+ self .x = x
1476
+
1477
+ class C (P ): pass
1478
+
1479
+ c = C (1 )
1480
+ self .assertIsInstance (c , C )
1481
+ self .assertEqual (c .x , 1 )
1482
+
1457
1483
def test_cannot_instantiate_abstract (self ):
1458
1484
@runtime_checkable
1459
1485
class P (Protocol ):
Original file line number Diff line number Diff line change @@ -662,7 +662,8 @@ def _proto_hook(other):
662
662
isinstance (base , _ProtocolMeta ) and base ._is_protocol ):
663
663
raise TypeError ('Protocols can only inherit from other'
664
664
f' protocols, got { repr (base )} ' )
665
- cls .__init__ = _no_init
665
+ if cls .__init__ is Protocol .__init__ :
666
+ cls .__init__ = _no_init
666
667
667
668
def runtime_checkable (cls ):
668
669
"""Mark a protocol class as a runtime protocol, so that it
You can’t perform that action at this time.
0 commit comments