Подсказки типа теряются, когда декоратор оборачивается как метод класса?Python

Программы на Python
Ответить
Anonymous
 Подсказки типа теряются, когда декоратор оборачивается как метод класса?

Сообщение Anonymous »

Рассмотрим следующий код:

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

from typing import Any, Callable, Coroutine

class Cache[**P, R]:
@classmethod
def decorate(cls, **params):
def decorator(f: Callable[P, Coroutine[Any, Any, R]]) -> Callable[P, Coroutine[Any, Any, R]]:
return f # in the real world, we instantiate a Cache here
return decorator

@Cache.decorate()
async def some_function(i: int) -> int:
return i + 1

cached_function = Cache.decorate()(some_function)
Если я спрошу тип Cache.decorate перед оболочкой @classmethod ( проверяя слово «украсить» в приведенном выше коде), он возвращает:

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

(method) def decorate(
cls: type[Self@Cache[P@Cache, R@Cache]],
**params: Unknown
) -> ((f: ((**P@Cache) -> (Coroutine[Any, Any, R@Cache])) -> ((**P@Cache) -> Coroutine[Any, Any, R@Cache]))
Мне кажется, что он понимает, что P (типы аргументов) и R (типы возвращаемых значений) подключены правильно.Однако, если я попрошу его проанализировать Cache.decorate в контексте, где он используется в качестве декоратора, он вернет:

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

(method) def decorate(**params: Unknown) -> ((f: ((...) -> Coroutine[Any, Any, Unknown])) -> ((...) -> Coroutine[Any, Any, Unknown]))
...то есть связь между типами ввода и типами вывода полностью отброшена!

Я могу избежать этой проблемы, сделав декор отдельной функцией, а не частью класса Cache, как показано ниже:

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

class Cache[**P, R]:
...

def decorate[**P, R](**params):
def decorator(f: Callable[P, Coroutine[Any, Any, R]]) -> Callable[P, Coroutine[Any, Any, R]]:
return f # in the real world, we instantiate a Cache[**P,R] here
return decorator
Можно ли избежать этого обходного пути? Зачем это нужно?

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

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

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

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

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

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