Skip to content

Commit

Permalink
update: Type annotations are not allowed for enum members
Browse files Browse the repository at this point in the history
Co-authored-by: Ali Hamdan <[email protected]>
  • Loading branch information
terencehonles and hamdanal committed Aug 6, 2024
1 parent dc00ef6 commit 50d0967
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 42 deletions.
3 changes: 3 additions & 0 deletions mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -4213,6 +4213,9 @@ def analyze_name_lvalue(
lvalue,
)

if explicit_type and has_explicit_value:
self.fail("Type annotations are not allowed for enum members", 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, has_explicit_value)
Expand Down
4 changes: 2 additions & 2 deletions mypyc/test-data/run-classes.test
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,8 @@ from enum import Enum

class TestEnum(Enum):
_order_ = "a b"
a : int = 1
b : int = 2
a = 1
b = 2

@classmethod
def test(cls) -> int:
Expand Down
23 changes: 22 additions & 1 deletion test-data/unit/check-enum.test
Original file line number Diff line number Diff line change
Expand Up @@ -1764,7 +1764,7 @@ class B(A):
x = 1 # E: Cannot override writable attribute "x" with a final one

class A1(Enum):
x: int = 1
x: int = 1 # E: Type annotations are not allowed for enum members
class B1(A1): # E: Cannot extend enum with existing members: "A1"
pass

Expand Down Expand Up @@ -2185,3 +2185,24 @@ reveal_type(A.y.value) # N: Revealed type is "Literal[2]?"
def some_a(a: A):
reveal_type(a.value) # N: Revealed type is "Union[Literal[1]?, Literal[2]?]"
[builtins fixtures/dict.pyi]


[case testErrorOnAnnotatedMember]
from enum import Enum

class Medal(Enum):
gold: int = 1 # E: Type annotations are not allowed for enum members
silver: str = 2 # E: Type annotations are not allowed for enum members \
# E: Incompatible types in assignment (expression has type "int", variable has type "str")
bronze = 3


[case testEnumMemberWithPlaceholder]
from enum import Enum

class Pet(Enum):
CAT = ...
DOG: str = ... # E: Type annotations are not allowed for enum members \
# E: Incompatible types in assignment (expression has type "ellipsis", variable has type "str")

[file test.pyi]
36 changes: 0 additions & 36 deletions test-data/unit/check-python311.test
Original file line number Diff line number Diff line change
@@ -1,39 +1,3 @@
[case testMatchLiteralPatternEnumWithNonMember-xfail]
from enum import Enum, nonmember
from typing import NoReturn
def assert_never(x: NoReturn) -> None: ...

class int:
def __new__(cls, value: int): pass

class Medal(int, Enum):
prize: str = nonmember("nothing")

def __new__(cls, value: int, prize: str | None = None) -> Medal:
enum = int.__new__(cls, value)
enum._value_ = value
if prize is not None:
enum.prize = prize
return enum

gold = (1, 'cash prize')
silver = (2, 'sponsorship')
bronze = (3,)

m: Medal

match m:
case Medal.gold:
reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.gold]"
case Medal.silver:
reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.silver]"
case Medal.bronze:
reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.bronze]"
case _ as unreachable:
assert_never(unreachable)

[builtins fixtures/tuple.pyi]

[case testTryStarSimple]
try:
pass
Expand Down
16 changes: 13 additions & 3 deletions test-data/unit/pythoneval.test
Original file line number Diff line number Diff line change
Expand Up @@ -1601,14 +1601,24 @@ _testSpecialTypingProtocols.py:8: error: Statement is unreachable
[case testEnumValueWithPlaceholderNodeType]
# https://github.com/python/mypy/issues/11971
from enum import Enum
from typing import Callable, Dict
from typing import Any, Callable, Dict
class Foo(Enum):
Bar: Foo = Callable[[str], None]
Baz: Foo = Callable[[Dict[str, "Missing"]], None]
Baz: Any = Callable[[Dict[str, "Missing"]], None]

reveal_type(Foo.Bar)
reveal_type(Foo.Bar.value) # this should probably not be "Foo" https://typing.readthedocs.io/en/latest/spec/enums.html#member-values
reveal_type(Foo.Baz)
reveal_type(Foo.Baz.value)
[out]
_testEnumValueWithPlaceholderNodeType.py:5: error: Type annotations are not allowed for enum members
_testEnumValueWithPlaceholderNodeType.py:5: error: Incompatible types in assignment (expression has type "<typing special form>", variable has type "Foo")
_testEnumValueWithPlaceholderNodeType.py:6: error: Incompatible types in assignment (expression has type "<typing special form>", variable has type "Foo")
_testEnumValueWithPlaceholderNodeType.py:6: error: Type annotations are not allowed for enum members
_testEnumValueWithPlaceholderNodeType.py:6: error: Name "Missing" is not defined
_testEnumValueWithPlaceholderNodeType.py:8: note: Revealed type is "Literal[_testEnumValueWithPlaceholderNodeType.Foo.Bar]?"
_testEnumValueWithPlaceholderNodeType.py:9: note: Revealed type is "_testEnumValueWithPlaceholderNodeType.Foo"
_testEnumValueWithPlaceholderNodeType.py:10: note: Revealed type is "Literal[_testEnumValueWithPlaceholderNodeType.Foo.Baz]?"
_testEnumValueWithPlaceholderNodeType.py:11: note: Revealed type is "Any"

[case testTypeshedRecursiveTypesExample]
from typing import List, Union
Expand Down

0 comments on commit 50d0967

Please sign in to comment.