如何在mypy中创建一个也接受自己的子类的泛型引用类型?

2024-09-30 02:17:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我在MongoDB上使用了Pydantic,包括我在这里描述的ID文档,一切都很好。但是,我也希望能够在不同文档之间键入引用。我能够让它半途而废,这可以在这段代码的最后部分看到

from typing import TypeVar, Generic
from pydantic import BaseModel, Field

ModelType = TypeVar("ModelType", bound="MyBaseModel")


class IDType(str):
    pass


class ReferenceId(IDType, Generic[ModelType]):
    pass


class MyBaseModel(BaseModel):
    id: IDType = Field(default_factory=IDType)


class MySubclassModel(MyBaseModel):
    pass


class AnotherSubclassModel(MyBaseModel):
    reference_to_my_subclass: ReferenceId[MySubclassModel]


class YetAnotherSubclassModel(MyBaseModel):
    reference_to_another_subclass: ReferenceId[AnotherSubclassModel]


# Obviously fails but I want those to pass:

a = AnotherSubclassModel(reference_to_my_subclass=MyBaseModel().id)
# Expected type 'ReferenceId[MySubclassModel]', got 'IDType' instead
x = YetAnotherSubclassModel(reference_to_another_subclass=a.id)
# Expected type 'ReferenceId[AnotherSubclassModel]', got 'IDType' instead


# But this works as I want
def my_function(reference_to_my_subclass: ReferenceId[MySubclassModel]):
    pass

my_function(a.reference_to_my_subclass)


# While these will fail, and I want them to fail:

# This one fails for the reason that I don't want, but at least fails
my_function(a.id)
# Expected type 'ReferenceId[MySubclassModel]', got 'IDType' instead

# This one for the right reason
my_function(x.reference_to_another_subclass)
# Expected type 'ReferenceId[MySubclassModel]', got 'ReferenceId[AnotherSubclassModel]' instead

可能解决方案在于以某种方式使用MyBaseModel.id引用“this subclass class class”,但我不确定如何实现这一点


Tags: toidmytypepassclassexpectedreference

热门问题