В плагине Mypy `get_method_hook` отсутствует `body` в `ClassDef` для импортированного типаPython

Программы на Python
Ответить
Anonymous
 В плагине Mypy `get_method_hook` отсутствует `body` в `ClassDef` для импортированного типа

Сообщение Anonymous »

У меня возникла проблема с get_method_hook в простом плагине mypy. Я не уверен, является ли это ошибкой в ​​mypy или у меня ошибочные ожидания относительно доступности информации на определенном этапе.
Плагин должен читать свойства класса на которого вызывается функция вызова, извлеките все свойства из класса и измените тип возвращаемого значения вызова на 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
Документации по плагинам mypy практически нет. Является ли просмотр узла AST ClassDef правильным подходом для извлечения подробной информации, такой как внутреннее поле свойств external и external2 MyClass?

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

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

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

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

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

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