MyPy 给出 "incompatible type "auto"; expected "str" " auto() 与从 str 继承的枚举一起使用时的错误

MyPy gives an "incompatible type "auto"; expected "str" " error when using auto() with Enums inheriting from str

Python 枚举的常见做法是从 str 继承,然后将 _generate_next_value 覆盖为 return 枚举名称,以便 auto() 函数可以用来简单地 return 作为字符串的名称。但是,这会在 MyPy 中引发错误。

例如,如果您声明:

from enum import Enum, auto

class StrEnum(str, Enum):
    def _generate_next_value_(name, start, count, last_values):
        return name

class Foo(StrEnum):
    bar = auto()
    baz = auto()

def takes_a_string(s: str):
   pass

takes_a_string(s=Foo.bar)

MyPy 会报错

Argument "s" to "takes_a_string" has incompatible type "auto"; expected "str"

另外尝试向 _generate_next_value 添加类型提示将导致错误,例如:

Signature of "generate_next_value" incompatible with supertype "Enum"
Self argument missing for a non-static method (or an invalid type for self)

如何在不使用 # type: ignore 的情况下解决这个问题?

如果您将 enum.auto 子类化为:

from enum import auto

class autostr(auto):
    value: str = _auto_null

然后

class Foo(StrEnum):
    bar = autostr()
    baz = autostr()

def takes_a_string(s: str):
   pass

takes_a_string(s=Foo.bar)

将顺利通过 MyPy 类型检查。

此外,您可以将 StrEnum._generate_next_value_ 更改为 staticmethod:

class StrEnum(str, Enum):
    @staticmethod
    def _generate_next_value_(name, start: int, count: int, last_values: List[Any]) -> str:
        return name

避免 MyPy 抱怨超类型不兼容

如 Guido 本人所建议:https://github.com/python/mypy/issues/7591