使用下面的代码
def incr[T: int | None](value: T) -> T:
if value is None:
return value
return value + 1
incr(None)
incr(1)
运行 mypy 出现错误:
main.py:4: error: Incompatible return value type (got "int", expected "T") [return-value] Found 1 error in 1 file (checked 1 source file)
为什么会出现这种情况?在我看来,该行返回了正确的类型。 注意:此类类型注释的目标是表明该函数仅在给定 None 作为输入时才返回 None
T: int | None
是一个 类型变量,具有 上限。它表示如果您传递 int | None
的 任何subtype,您将获得该子类型。
mypy 警告您,如果您传递
int
的子类,该函数在运行时会出现错误行为:
import typing as t
def incr[T: int | None](value: T) -> T:
if value is None:
return value
return value + 1 # error: Incompatible return value type (got "int", expected "T") [return-value]
class MyInt(int):
pass
>>> result: t.Final = incr(MyInt(3))
>>> if t.TYPE_CHECKING:
... reveal_type(result) # note: Revealed type is "MyInt"
>>> print(type(result))
<class 'int'>
解决方案是使用约束类型变量,其行为是将结果向上转换为适当的约束类型:
def incr[T: (int, None)](value: T) -> T: ...
>>> if t.TYPE_CHECKING:
... reveal_type(result) # note: Revealed type is "builtins.int"