Skip to content

Commit b0c7eb9

Browse files
gh-119946: make Protocol compatible with Enum instantiation
1 parent c6f7368 commit b0c7eb9

2 files changed

Lines changed: 25 additions & 1 deletion

File tree

Lib/test/test_enum.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2478,6 +2478,26 @@ class SomeEnum(Enum):
24782478
globals()['T'] = T
24792479
test_pickle_dump_load(self.assertIs, SomeEnum.first)
24802480

2481+
def test_protocol_mixin_as_enum_member_value(self):
2482+
class Example(typing.Protocol):
2483+
def method(self) -> None: ...
2484+
2485+
class Impl(Example):
2486+
def method(self) -> None: ...
2487+
2488+
class CompatEnumType(type(typing.Protocol), EnumType): ...
2489+
2490+
class ProtoEnum(Example, Enum, metaclass=CompatEnumType):
2491+
__qualname__ = 'ProtoEnum' # needed for pickle protocol 4
2492+
impl = Impl()
2493+
2494+
self.assertIsInstance(ProtoEnum.impl.value, Impl)
2495+
globals()['Example'] = Example
2496+
globals()['Impl'] = Impl
2497+
globals()['ProtoEnum'] = ProtoEnum
2498+
ProtoEnum.__reduce_ex__ = enum.pickle_by_enum_name
2499+
test_pickle_dump_load(self.assertIs, ProtoEnum.impl)
2500+
24812501
def test_duplicate_values_give_unique_enum_items(self):
24822502
class AutoNumber(Enum):
24832503
first = ()

Lib/typing.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1882,7 +1882,11 @@ def _get_protocol_attrs(cls):
18821882
def _no_init_or_replace_init(self, *args, **kwargs):
18831883
cls = type(self)
18841884

1885-
if cls._is_protocol:
1885+
# Determine if this is a protocol or a concrete subclass.
1886+
# Note: not using cls._is_protocol here,
1887+
# since this may be called before __init_subclass__ is resolved.
1888+
# for example when subclassing enum.Enum.
1889+
if any(b is Protocol for b in cls.__bases__):
18861890
raise TypeError('Protocols cannot be instantiated')
18871891

18881892
# Already using a custom `__init__`. No need to calculate correct

0 commit comments

Comments
 (0)