如何避免 "str" 的 "Argument 1 to "join" 具有不兼容的类型 "Callable[[], List[str]]";预期 "Iterable[str]"

How to avoid "Argument 1 to "join" of "str" has incompatible type "Callable[[], List[str]]"; expected "Iterable[str]"

重现此错误的最小示例如下所示

from enum import Enum
from typing import List


class Stuff(Enum):
    A = 'something'
    B = 'something_else'
    C = 'even_more'
    
    @classmethod
    @property
    def important_stuff(cls) -> List[str]:
        return [cls.A.value, cls.C.value]


print(f'{", ".join(Stuff.important_stuff)}')

打印

something, even_more

符合预期。

当我用 mypy 测试这个文件时,我收到

error: Argument 1 to "join" of "str" has incompatible type "Callable[[], List[str]]"; expected "Iterable[str]"

究竟是什么导致了这个问题,我该如何避免?

这看起来是 mypy 需要一些 hard-coded 逻辑来处理 class 方法的情况。 mypy 可以在普通 class 上处理相同的 classmethod-wrapped 属性 就好了。(好吧,差不多。你需要一个 实例 Stuff,而不是 class 本身,调用 important_stuff。)只要您访问 Enum subclass =32=] 通过 Stuff 的实例而不是 class 本身。

$ cat tmp.py
from enum import Enum
from typing import List


class Stuff:
    A = 'something'
    B = 'something_else'
    C = 'even_more'

    @classmethod
    @property
    def important_stuff(cls) -> List[str]:
        return [cls.A, cls.C]


print(f'{", ".join(Stuff().important_stuff)}')

$ mypy tmp.py
Success: no issues found in 1 source file

如果是这种情况,并且在 mypy 固定之前,您可以将该值显式转换为 Iterable[str]

from typing import cast, Iterable


print(f'{", ".join(cast(Iterable[str], Stuff.important_stuff))}')