考虑以下代码:
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)
如果我询问 pyright 包装器Cache.decorate
之前的类型(检查上面代码中的@classmethod
单词),它会返回:decorate
(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]))
...也就是说,输入类型和输出类型之间的关系已被完全丢弃!