以下面的代码示例为例:
from typing import Literal, overload, Tuple
SpecificStrings = Literal['bacon', 'eggs']
@overload
def my_func(foo: SpecificStrings) -> float:
...
@overload
def my_func(foo: str) -> bool:
...
def my_func(foo):
if foo in ('bacon', 'eggs'):
return 101.5
else:
return bool(foo)
def main() -> Tuple[float, bool]:
x = my_func('bacon') # float
y = my_func('any other string') # bool
return x, y
基本思想是my_func
使用特定字符串调用if'bacon'
或'eggs'
返回类型应为float
. 如果使用任何其他字符串,则返回类型应为bool
.
直观地说,我希望在不太具体的注释之前首先检查更具体的注释 ( ) 。foo: SpecificStrings
: str
但是,当使用 键入检查此文件时mypy
,我收到一个错误:
t.py:6:错误:重载的函数签名 1 和 2 与不兼容的返回类型重叠
此外,当使用 进行类型检查时pyright
,没有发现错误。
似乎这可能是 中的错误、中mypy
的错误pyright
,或者可能是其他东西...... PEP484似乎没有表明在这种情况下应该是什么行为。
是否有另一种方法来键入这种情况,使其工作(也就是说,x
在y
上面的例子中,和被理解为它们各自的类型float
和bool
)与mypy
?
编辑:
有趣的是,使用Enum
而不是Literal
似乎是一种解决方法:
from enum import Enum
class SpecificStrings(Enum):
bacon = 'bacon'
eggs = 'eggs'
reveal_type()
在这种情况下,与 pyright 和 mypy 一起使用会显示正确的类型。
# pyright
C:\Users\path\to\t.py
C:\Users\path\to\t.py:38:13 - information: Type of "x" is "float"
C:\Users\path\to\t.pyt.py:39:13 - information: Type of "y" is "bool"
0 errors, 0 warnings, 2 informations
# mypy
t.py:38: note: Revealed type is "builtins.float"
t.py:39: note: Revealed type is "builtins.bool"
对我来说,这引出了另一个问题:为什么Enum
有效但无效Literal
?
然而,令人沮丧的是,PyCharm 并没有做同样的事情: