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
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