Python (pydantic) сравнение аннотаций
Возможно ли сравнить аннотации на вхождение между собой? В примере используется pydantic, однако его использование, в целом, не обязательно
from pydantic import BaseModel
from typing import Union
class Test1(BaseModel):
simple: list[str]
hard: Union[list[str], list[int], None] = None
class Test2(BaseModel):
simple: list[str]
hard: list[int]
m_f_1 = Test1.model_fields
m_f_2 = Test2.model_fields
print(m_f_1['simple'].annotation == m_f_2['simple'].annotation)
print(m_f_1['hard'].annotation == m_f_2['hard'].annotation)
dct = {'simple':['stroka'], 'hard':[1]}
t1 = Test1(**dct)
t2 = Test2(**dct)
Поле hard
в объекте Test1
принимает более широкий спектр объектов, но при этом всё что подходит для поля в объекте Test2
будет подходить и для поля в объекте Test1
. Нужно сравнить эти поля на то, входит ли аннотация одного поля в аннотацию другого.
Сравнение напрямую ==
работает корректно для абсолютно одинаковых аннотаций (что логично).
Думал про вариант сгенерировать левый объект, но вероятно, есть чуть более простой и корректный вариант сравнить аннотации.
Ответы (1 шт):
Если преобразовать аннотацию с Union в строку:
str(m_f_1['hard'].annotation)
То получится следующее:
'typing.Union[list[str], list[int], NoneType]'
А если преобразовать аннотацию GenericAlias
m_f_2['hard'].annotation
То получается следующий вывод:
'list[int]'
Таким образом, можно проверить вхождение типа данных в аннотацию при помощи in
.
У меня получился такой код:
from types import GenericAlias
a = m_f_1['hard'].annotation
b = m_f_2['hard'].annotation
if isinstance(a, GenericAlias) and isinstance(b, GenericAlias):
print(a == b)
elif isinstance(a, GenericAlias):
print(str(a) in str(b))
elif isinstance(b, GenericAlias):
print(str(b) in str(a))
Вывод:
True