为什么 mypy 在无法注释时会抱怨列表理解?

Why is mypy complaining about list comprehension when it can't be annotated?

当无法使用 MyPy 注释此类变量时,为什么 Mypy 抱怨它需要列表理解变量的类型注释?

具体来说,我该如何解决以下错误:

from enum import EnumMeta

def spam( y: EnumMeta ):
    return [[x.value] for x in y]  Mypy: Need type annotation for 'x' 

cast 不起作用:

return [[cast(Enum, x).value] for x in y]  Mypy: Need type annotation for 'x'  

即使 Mypy 不支持注释 (x:Enum),在这种情况下,我看到变量的 usage 可以使用 cast 进行注释()。然而,cast(Enum, x) 并没有阻止 Mypy 抱怨变量没有首先被注释。

#type: 不起作用:

return [[x.value] for x in y] # type: Enum  Mypy: Misplaced type annotation

我还看到 for 循环变量可以使用注释 # type: () 进行注释。但是,# type: Enum 不适用于列表理解的 for.

在列表推导式中,必须强制转换迭代器而不是元素。

from typing import Iterable, cast
from enum import EnumMeta, Enum

def spam(y: EnumMeta):
    return [[x.value] for x in cast(Iterable[Enum], y)]

这也允许 mypy 推断 x 的类型。此外,在运行时它只执行 1 次转换而不是 n 次转换。

如果spam可以消化任何产生枚举的可迭代对象,直接键入提示会更容易。

from typing import Iterable
from enum import Enum

def spam(y: Iterable[Enum]):
    return [[x.value] for x in y]

MisterMyagi 的 is the best solution for this specific case. It may be worth noting, however, that it is also possible to declare the type of a variable before that variable is defined. The following also passes MyPy:

from enum import Enum

def spam(y: type[Enum]):
    x: Enum
    return [[x.value] for x in y]