Python: совместное использование аннотаций типов между Protocol и TypedDictPython

Программы на Python
Ответить
Anonymous
 Python: совместное использование аннотаций типов между Protocol и TypedDict

Сообщение Anonymous »

Возьмем этот простой пример:

Код: Выделить всё

from __future__ import annotations
import typing as t

class MyType:
def __init__(self, s: str, i: int) -> None:
self.s = s
self.i = i

class MyProto(t.Protocol):
s: str
i: int

class MyDict(t.TypedDict):
s: str
i: int

def my_serializer(inst: MyProto) -> MyDict:
return {"s": inst.s, "i": inst.i}

d = my_serializer(MyType("a", 1))
Все проверки типов пройдены.
Теперь предположим, что MyType на самом деле является классом ORM со множеством атрибутов, которые являются источником истины. для набора протокола и дикта. Кажется немного излишним сохранять одинаковые аннотации в теле класса Protocol и в теле класса TypedDict каждый раз, когда атрибут добавляется в класс.
Я хотел бы знать, есть ли там это способ централизованно определить аннотации типов и сообщить mypy, что это определения типов как для протокола, так и для класса dict.
Я попробовал это:

Код: Выделить всё

class TypeMixin:
s: str
i: int

class MyProto(TypeMixin, t.Protocol):
pass

class MyDict(TypeMixin, t.TypedDict):
pass
Однако mypy жалуется:

Код: Выделить всё

test.py:15: error: All bases of a protocol must be protocols
test.py:19: error: All bases of a new TypedDict must be TypedDict types
... и это на самом деле ошибка типа во время выполнения.
А это:

Код: Выделить всё

annos = {"s": "str", "i": "int"}
MyProto = type("MyProto", (t.Protocol,), {"__annotations__": annos})
MyDict = type("MyDict", (t.TypedDict,), {"__annotations__": annos})

def my_serializer(inst: MyProto) -> MyDict:
return {"s": inst.s, "i": inst.i}
Это работает, но mypy жалуется, и я предполагаю, что все равно слишком динамично для mypy:

Код: Выделить всё

test.py:12: error: Argument 2 to "type" has incompatible type "Tuple[_SpecialForm]"; expected "Tuple[type, ...]"
test.py:13: error: Argument 2 to "type" has incompatible type "Tuple[object]"; expected "Tuple[type, ...]"
test.py:16: error: Variable "topsport.events.test.MyProto" is not valid as a type
test.py:16: error: Variable "topsport.events.test.MyDict" is not valid as a type
test.py:17: error: MyProto? has no attribute "s"
test.py:17: error: MyProto? has no attribute "i"
Невозможно ли то, что я пытаюсь сделать?

Подробнее здесь: https://stackoverflow.com/questions/603 ... -typeddict
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»