Skip to content

Commit be163fc

Browse files
committed
fixup! Support overriding dunder attributes in Enum subclass
1 parent ffa4ec8 commit be163fc

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

mypy/checker.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1898,8 +1898,10 @@ def check_enum(self, defn: ClassDef) -> None:
18981898
for sym in defn.info.names.values():
18991899
if (isinstance(sym.node, Var) and sym.node.has_explicit_value and
19001900
sym.node.name == '__members__'):
1901+
# `__members__` will always be overwritten by `Enum` and is considered
1902+
# read-only so we disallow assigning a value to it
19011903
self.fail(
1902-
'Cannot declare read-only attribute "__members__"', sym.node
1904+
message_registry.CANNOT_WRITE_ENUM_READONLY_MEMBERS, sym.node
19031905
)
19041906
for base in defn.info.mro[1:-1]: # we don't need self and `object`
19051907
if base.is_enum and base.fullname not in ENUM_BASES:

mypy/message_registry.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,11 @@ def format(self, *args: object, **kwargs: object) -> "ErrorMessage":
204204
)
205205
CANNOT_MAKE_DELETABLE_FINAL: Final = ErrorMessage("Deletable attribute cannot be final")
206206

207+
# Enum
208+
CANNOT_WRITE_ENUM_READONLY_MEMBERS: Final = ErrorMessage(
209+
'Cannot declare read-only attribute "__members__"'
210+
)
211+
207212
# ClassVar
208213
CANNOT_OVERRIDE_INSTANCE_VAR: Final = ErrorMessage(
209214
'Cannot override instance variable (previously declared on base class "{}") with class '

test-data/unit/check-enum.test

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1891,7 +1891,7 @@ def f2(c: C, a: Any) -> None:
18911891

18921892
[case testCanOverrideDunderAttributes]
18931893
import typing
1894-
from enum import Enum
1894+
from enum import Enum, Flag
18951895

18961896
class BaseEnum(Enum):
18971897
__dunder__ = 1
@@ -1902,7 +1902,20 @@ class Override(BaseEnum):
19021902
__labels__ = {1: "1"}
19031903

19041904
Override.__dunder__ = 3
1905+
BaseEnum.__dunder__ = 3
19051906
Override.__labels__ = {2: "2"}
1907+
1908+
class FlagBase(Flag):
1909+
__dunder__ = 1
1910+
__labels__: typing.Dict[int, str]
1911+
1912+
class FlagOverride(FlagBase):
1913+
__dunder__ = 2
1914+
__labels = {1: "1"}
1915+
1916+
FlagOverride.__dunder__ = 3
1917+
FlagBase.__dunder__ = 3
1918+
FlagOverride.__labels__ = {2: "2"}
19061919
[builtins fixtures/dict.pyi]
19071920

19081921
[case testCanNotInitialize__members__]

0 commit comments

Comments
 (0)