diff --git a/mypy/semanal.py b/mypy/semanal.py index 49c24cde0447..e2d6abe7e7d3 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -2748,6 +2748,13 @@ def analyze_name_lvalue(self, existing = names.get(name) outer = self.is_global_or_nonlocal(name) + if kind == MDEF and isinstance(self.type, TypeInfo) and self.type.is_enum: + # Special case: we need to be sure that `Enum` keys are unique. + if existing: + self.fail('Attempted to reuse member name "{}" in Enum definition "{}"'.format( + name, self.type.name, + ), lvalue) + if (not existing or isinstance(existing.node, PlaceholderNode)) and not outer: # Define new variable. var = self.make_name_lvalue_var(lvalue, kind, not explicit_type) diff --git a/test-data/unit/check-enum.test b/test-data/unit/check-enum.test index 5200c00d3f28..e49ad7d8fa0e 100644 --- a/test-data/unit/check-enum.test +++ b/test-data/unit/check-enum.test @@ -1360,3 +1360,34 @@ class E(IntEnum): A = N(0) reveal_type(E.A.value) # N: Revealed type is "__main__.N" + + +[case testEnumReusedKeys] +# https://github.com/python/mypy/issues/11248 +from enum import Enum +class Correct(Enum): + x = 'y' + y = 'x' +class Foo(Enum): + A = 1 + A = 'a' # E: Attempted to reuse member name "A" in Enum definition "Foo" \ + # E: Incompatible types in assignment (expression has type "str", variable has type "int") +reveal_type(Foo.A.value) # N: Revealed type is "builtins.int" + +class Bar(Enum): + A = 1 + B = A = 2 # E: Attempted to reuse member name "A" in Enum definition "Bar" +class Baz(Enum): + A = 1 + B, A = (1, 2) # E: Attempted to reuse member name "A" in Enum definition "Baz" +[builtins fixtures/tuple.pyi] + +[case testEnumReusedKeysOverlapWithLocalVar] +from enum import Enum +x = 1 +class Foo(Enum): + x = 2 + def method(self) -> None: + x = 3 +x = 4 +[builtins fixtures/bool.pyi]