Why does Mypy complain that it requires a type annotation for a list comprehension variable, when it is impossible to annotate such a variable using MyPy?
Specifically, how can I resolve the following error:
from enum import EnumMeta
def spam( y: EnumMeta ):
return [[x.value] for x in y] 🠜 Mypy: Need type annotation for 'x'
cast
doesn't work:
return [[cast(Enum, x).value] for x in y] 🠜 Mypy: Need type annotation for 'x'
Even though Mypy doesn't support annotations (x:Enum
) in such a case I see the usage of the variable can be annotated using cast
(see this post). However, cast(Enum, x)
doesn't stop Mypy complaining that the variable isn't annotated in the first place.
#type:
doesn't work:
return [[x.value] for x in y] # type: Enum 🠜 Mypy: Misplaced type annotation
I also see that a for
loop variable can be annotated using a comment, # type:
(see this post). However, # type: Enum
doesn't work for list comprehension's for
.
In a list comprehension, the iterable must be cast instead of the elements.
from typing import Iterable, cast
from enum import EnumMeta, Enum
def spam(y: EnumMeta):
return [[x.value] for x in cast(Iterable[Enum], y)]
This allows mypy
to infer the type of x
as well. In addition, at runtime it performs only 1 cast instead of n casts.
If spam
can digest any iterable that produces enums, it is easier to type hint this directly.
from typing import Iterable
from enum import Enum
def spam(y: Iterable[Enum]):
return [[x.value] for x in y]