结合 mypy Union 和嵌套的 TypedDict 导致 mypy 错误:不兼容 return 值
Combining mypy Union and nested TypedDict causes mypy errror: incompatible return value
我想将 TypedDict
与 Union
合并。这样一个函数就可以 return A
或 B
。 Mypy 能够直接正确检测 TypedDict
return 类型。但是当 TypedDict
嵌套在 Union
中时,它不起作用。
from typing_extensions import TypedDict
from typing import Union
class A(TypedDict):
a: str
class B(TypedDict):
b: str
def works() -> A:
return {'a': 'value'}
# Works as expected
def problem() -> Union[A, B]:
return {'a': 'value'}
# mypy_error: Incompatible return value type (got "Dict[str, str]", expected "Union[A, B]")
# Reports an error while it should be valid
def workaround() -> Union[A, B]:
x: A = {'a': 'value'}
return x
# This works again but is not very elegant
一种可能的解决方法是分配给临时 returned 类型提示变量(参见 workaround()
)。有更优雅的方法吗?
注:Python3.7
引自PEP 589:
An explicit [TypedDict] type annotation is generally needed, as otherwise an ordinary dictionary type could be assumed by a type checker, for backwards compatibility. When a type checker can infer that a constructed dictionary object should be a TypedDict, an explicit annotation can be omitted.
所以在代码中明确定义类型没有错。另一种可能是直接"instantiate"A
:
def problem() -> Union[A, B]:
return A(a='value')
虽然这当然只是一个语法糖,在运行时将被替换为dict
。
我想将 TypedDict
与 Union
合并。这样一个函数就可以 return A
或 B
。 Mypy 能够直接正确检测 TypedDict
return 类型。但是当 TypedDict
嵌套在 Union
中时,它不起作用。
from typing_extensions import TypedDict
from typing import Union
class A(TypedDict):
a: str
class B(TypedDict):
b: str
def works() -> A:
return {'a': 'value'}
# Works as expected
def problem() -> Union[A, B]:
return {'a': 'value'}
# mypy_error: Incompatible return value type (got "Dict[str, str]", expected "Union[A, B]")
# Reports an error while it should be valid
def workaround() -> Union[A, B]:
x: A = {'a': 'value'}
return x
# This works again but is not very elegant
一种可能的解决方法是分配给临时 returned 类型提示变量(参见 workaround()
)。有更优雅的方法吗?
注:Python3.7
引自PEP 589:
An explicit [TypedDict] type annotation is generally needed, as otherwise an ordinary dictionary type could be assumed by a type checker, for backwards compatibility. When a type checker can infer that a constructed dictionary object should be a TypedDict, an explicit annotation can be omitted.
所以在代码中明确定义类型没有错。另一种可能是直接"instantiate"A
:
def problem() -> Union[A, B]:
return A(a='value')
虽然这当然只是一个语法糖,在运行时将被替换为dict
。