Skip to content

Commit f2978c3

Browse files
authored
Adds check for unique enum keys (#11267)
Closes #11248
1 parent 15f2385 commit f2978c3

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

mypy/semanal.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2748,6 +2748,13 @@ def analyze_name_lvalue(self,
27482748
existing = names.get(name)
27492749

27502750
outer = self.is_global_or_nonlocal(name)
2751+
if kind == MDEF and isinstance(self.type, TypeInfo) and self.type.is_enum:
2752+
# Special case: we need to be sure that `Enum` keys are unique.
2753+
if existing:
2754+
self.fail('Attempted to reuse member name "{}" in Enum definition "{}"'.format(
2755+
name, self.type.name,
2756+
), lvalue)
2757+
27512758
if (not existing or isinstance(existing.node, PlaceholderNode)) and not outer:
27522759
# Define new variable.
27532760
var = self.make_name_lvalue_var(lvalue, kind, not explicit_type)

test-data/unit/check-enum.test

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,3 +1360,34 @@ class E(IntEnum):
13601360
A = N(0)
13611361

13621362
reveal_type(E.A.value) # N: Revealed type is "__main__.N"
1363+
1364+
1365+
[case testEnumReusedKeys]
1366+
# https://github.com/python/mypy/issues/11248
1367+
from enum import Enum
1368+
class Correct(Enum):
1369+
x = 'y'
1370+
y = 'x'
1371+
class Foo(Enum):
1372+
A = 1
1373+
A = 'a' # E: Attempted to reuse member name "A" in Enum definition "Foo" \
1374+
# E: Incompatible types in assignment (expression has type "str", variable has type "int")
1375+
reveal_type(Foo.A.value) # N: Revealed type is "builtins.int"
1376+
1377+
class Bar(Enum):
1378+
A = 1
1379+
B = A = 2 # E: Attempted to reuse member name "A" in Enum definition "Bar"
1380+
class Baz(Enum):
1381+
A = 1
1382+
B, A = (1, 2) # E: Attempted to reuse member name "A" in Enum definition "Baz"
1383+
[builtins fixtures/tuple.pyi]
1384+
1385+
[case testEnumReusedKeysOverlapWithLocalVar]
1386+
from enum import Enum
1387+
x = 1
1388+
class Foo(Enum):
1389+
x = 2
1390+
def method(self) -> None:
1391+
x = 3
1392+
x = 4
1393+
[builtins fixtures/bool.pyi]

0 commit comments

Comments
 (0)