Как набрать аннотацию многоуровневого декоратораPython

Программы на Python
Anonymous
Как набрать аннотацию многоуровневого декоратора

Сообщение Anonymous »

Я пытаюсь аннотировать декоратор-инжектор, который вводит значение из глобального словаря в качестве аргумента ключевого слова в декорированную функцию при вызове функции.
Может ли кто-нибудь сталкиваться с аннотированием? декораторы с параметрами мне помогут?
Попробовал аннотировать, но застрял на следующих ошибках:

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

import functools
import inspect
from typing import Any, Callable, TypeVar, ParamSpec

Type = TypeVar('Type')
Param = ParamSpec('Param')
_INSTANCES = {}

def make_injectable(instance_name: str, instance: object) -> None:
_INSTANCES[instance_name] = instance

def inject(*instances: str) -> Callable[Param, Type]:

def get_function_with_instances(fn: Callable[Param, Type]) -> Callable[Param, Type]:
# This attribute is to easily access which arguments of fn are injectable
fn._injectable_args = instances

def handler(*args: Param.args, **kwargs: Param.kwargs) -> Type:
new_kwargs: dict[str, Any] = dict(kwargs).copy()
for instance in instances:
if instance in new_kwargs:
continue
if instance not in _INSTANCES:
raise ValueError(f"Instance {instance} was not initialized yet")
new_kwargs[instance] = _INSTANCES[instance]
return fn(*args, **new_kwargs)

if inspect.iscoroutinefunction(fn):
@functools.wraps(fn)
async def wrapper(*args: Param.args, **kwargs: Param.kwargs) -> Callable[Param, Type]:
return await handler(*args, **kwargs)

else:
@functools.wraps(fn)
def wrapper(*args: Param.args, **kwargs: Param.kwargs) -> Callable[Param, Type]:
return handler(*args, **kwargs)

return wrapper

return get_function_with_instances

Если я запущу mypy с этими аннотациями, я получу следующие ошибки, которые невозможно обойти без создания новых:

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

mypy injector.py --strict --warn-unreachable --allow-subclassing-any --ignore-missing-imports --show-error-codes --install-types --non-interactive

injector.py:33: error: "Callable[Param, Type]" has no attribute "_injectable_args"  [attr-defined]
injector.py:48: error: Returning Any from function declared to return "Callable[Param, Type]"  [no-any-return]
injector.py:48: error: Incompatible types in "await" (actual type "Type", expected type "Awaitable[Any]")  [misc]
injector.py:53: error: Incompatible return value type (got "Type", expected "Callable[Param, Type]")  [return-value]
injector.py:55: error: Incompatible return value type (got "Callable[Param, Coroutine[Any, Any, Callable[Param, Type]]]", expected "Callable[Param, Type]")  [return-value]
injector.py:57: error: Incompatible return value type (got "Callable[[Callable[Param, Type]], Callable[Param, Type]]", expected "Callable[Param, Type]")  [return-value]
Спасибо, что уделили время.

Подробнее здесь: https://stackoverflow.com/questions/749 ... -decorator

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