Mypy 失败,预期类型为“Type[T]”,改为“UnionType”

问题描述 投票:0回答:1

我使用 pydantic 从 JSON 文件加载数据,这些文件可以具有不同的参数,在本例中为 x 或 y。我使用

Loader
类将它们加载到 pydantic 模型中,以便我可以在运行时验证它们,但我无法使我的代码与 mypy 兼容。它失败并出现以下错误:
Expected type 'Type[T]', got 'UnionType' instead

我有 mypy 1.10.0 和 pydantic 2.7.0。

这是我的用例的可重现示例:

from typing import Iterator, Type, TypeVar, Union

from pydantic import BaseModel, TypeAdapter


class A(BaseModel):
    x: int


class B(BaseModel):
    y: int


T = TypeVar("T", bound=BaseModel)


class Loader:
    def load_models(self, model_class: Type[T]) -> Iterator[T]:
        # logic to load models
        my_dict = {"x": 1}  # fake data for testing
        yield TypeAdapter(model_class).validate_python(my_dict)
        my_dict = {"y": 2}  # fake data for testing
        yield TypeAdapter(model_class).validate_python(my_dict)


ModelAOrB = A | B

print(list(Loader().load_models(ModelAOrB)))

有没有办法让它与 mypy 一起工作?

python mypy pydantic
1个回答
0
投票

感谢这篇文章,我找到了一种方法来做我想做的事情,关键是使用 pydantic 中的

RootModel
并直接将其用作参数。不要忘记返回
.root
,mypy 现在接受以下代码:

class Loader:
    def load_models(self, root_model: type[RootModel[T]]) -> Iterator[T]:
        # logic to load models
        my_dict = {"x": 1}  # fake data for testing
        yield root_model.model_validate(my_dict).root # or root_model(**my_dict).root
        my_dict = {"y": 2}  # fake data for testing
        yield root_model.model_validate(my_dict).root # or root_model(**my_dict).root


ModelAOrB = A | B

print(list(Loader().load_models(RootModel[ModelAOrB])))
© www.soinside.com 2019 - 2024. All rights reserved.