oyb*_*lix 5 python typing mypy fastapi
我的任务是在我们的 FastAPI 项目中处理从 Mypy 0.770 到 0.870 的更新,这产生了一个我无法完全理解的错误。我的端点可以根据某些条件返回两个不同的模型,这在 endpont 装饰器中表示如下:
@router.get("/", response_model=Union[Model1, Model2])
Run Code Online (Sandbox Code Playgroud)
Mypy 0.870 现在抱怨这个,指出
Argument "response_model" to "get" of "APIRouter" has incompatible type "object"; expected "Optional[Type[Any]]"
Run Code Online (Sandbox Code Playgroud)
将其设置为单一类型,例如Model1甚至str消除错误。Any然而,这并不能正常工作。
现在,查看该get方法,我看到response_model参数的类型为Type[Any],我认为它必须是一个指针。
如何为我的 API 定义非简单的返回模型,并使 Mypy 开心?
编辑:我试图在较小的框架中重现该问题,但不能。以下代码工作正常:
from typing import Any, Type, Union
def test1(var, response_model: Type[Any]):
print(f"Accepted Type[Any], {var}")
def test2(var, response_model: Union[dict, set]):
print(f"Accepted Union, {var}")
def main():
test1('test1', response_model=Union[dict, set])
test2('test2', response_model=Union[dict, set])
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
这是较新版本的 mypy 中引入的兼容性问题。Github 上有一个关于此主题的未决问题: https://github.com/tiangolo/fastapi/issues/2279
在讨论中,他们提供了以下解决方法:
使用不同的方法创建类型别名:
NewModel = TypeVar('NewModel',Model1,Model2)
创建一个新的 Pydantic 模型:
class NewModel(BaseModel):
__root__: Union[Model1, Model2]
Run Code Online (Sandbox Code Playgroud)