Плагин Mypy для замены пользовательского TypeAlias ​​на NotRequiredPython

Программы на Python
Anonymous
Плагин Mypy для замены пользовательского TypeAlias ​​на NotRequired

Сообщение Anonymous »

Я хочу написать плагин mypy, чтобы ввести псевдоним типа для NotRequired[Optional[T]]. (Как я узнал в этом вопросе, невозможно написать этот псевдоним типа в простом Python, поскольку NotRequired не разрешен вне определения TypedDict.)
Моя идея — определить общий тип «Возможно», например:

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

# possibly.__init__.py

from typing import Generic, TypeVar

T = TypeVar("T")

class Possibly(Generic[T]):
pass
Затем я хочу, чтобы мой плагин заменял любое вхождение Возможно[X] на NotRequired[Optional[X]]. Я попробовал следующий подход:

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

# possibly.plugin

from mypy.plugin import Plugin

class PossiblyPlugin(Plugin):
def get_type_analyze_hook(self, fullname: str):
if fullname != "possibly.Possibly":
return
return self._replace_possibly

def _replace_possibly(self, ctx):
arguments = ctx.type.args
breakpoint()

def plugin(version):
return PossiblyPlugin
Я понимаю, что в точке останова мне нужно создать экземпляр подкласса mypy.types.Type на основе аргументов. Но я не нашел способа создать NotRequired. В mypy.types нет соответствующего типа. Я полагаю, что это может быть связано с тем, что typing.NotRequired — это не класс, а typing._SpecialForm. (Думаю, это связано с тем, что NotRequired не влияет на тип значения, а влияет на определение .__optional_keys__ TypedDict, в котором оно встречается.)
Итак, я подумал о другой стратегии: я мог бы проверить TypedDict, посмотреть, какие поля отмечены как «Возможно», и установить .__optional_keys__ TypedDict экземпляр, чтобы сделать поле необязательным, и замените тип «Возможно» на mypy.types.UnionType(*arguments, None). Но я не нашел, какой метод в mypy.plugin.Plugin использовать, чтобы получить TypedDict в контекст.
Итак, я застрявший. Я впервые копаюсь во внутреннем устройстве mypy. Не могли бы вы подсказать мне, как достичь того, чего я хочу?

Подробнее здесь: https://stackoverflow.com/questions/779 ... otrequired

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