Плагин должен читать свойства класса на которого вызывается функция вызова, извлеките все свойства из класса и измените тип возвращаемого значения вызова на TypedDict, который содержит все свойства класса.
Это прекрасно работает, если класс определен в том же модуль, в котором вызывается метод вызова. Если класс определен в другом модуле (т. е. импортирован), тело (из my_type.defn.defs.body) импортированного класса недоступно и, таким образом, доступно только доступна ограниченная информация из свойств (т. е. в данном случае только тип Outer, но нет информации о его параметрах).
Вот MWE, который не включает фактическая логика для создания TypedDict, поскольку это не имеет отношения к рассматриваемой проблеме.
Код: Выделить всё
# foo.py
from dataclasses import dataclass
from typing import Any
@dataclass
class Inner:
a: int
b: int
@dataclass
class Outer:
inner: Inner
@dataclass
class MyClass:
outer = Outer(inner=Inner(1, 2))
outer2 = Outer(inner=Inner(3, 4))
def invoke(self) -> dict[str, Any]:
return self.__dict__
# bar.py
from my_pkg.foo import MyClass
def bar():
b = MyClass(1, 2, 3)
result = b.invoke()
print(result["d"])
bar()
# plugin.py
from typing import Callable, cast
from mypy.plugin import (
MethodContext,
Plugin,
)
from mypy.types import (
Instance,
Type,
)
def alter_invoke_return_type(ctx: MethodContext) -> Type:
my_type = cast(Instance, ctx.type).type
for member_name, member_type in my_type.names.items():
print(f"Member property {member_name} has type {member_type}")
# TODO: How to wait until body from imported type has been analyzed to extract the
# 'inner' objects of a member variable type?
assert len(my_type.defn.defs.body) != 0, f"Type {my_type.fullname} has no body"
return ctx.default_return_type
class CustomPlugin(Plugin):
def get_method_hook(self, fullname: str) -> Callable[[MethodContext], Type] | None:
parts = fullname.split(".")
if parts[-1] == "invoke":
return alter_invoke_return_type
return None
def plugin(version: str):
return CustomPlugin
Подробнее здесь: https://stackoverflow.com/questions/792 ... orted-type
Мобильная версия