Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
405 views
in Technique[技术] by (71.8m points)

python - Typing function when decorator change generic return type

This is similar to Typing function when decorator change return type but this time with a generic return type:

from typing import Generic, TypeVar, Generic, Callable, Any, cast

T = TypeVar('T')

class Container(Generic[T]):
    def __init__(self, item: T):
        self.item: T = item

def my_decorator(f: Callable[..., T]) -> Callable[..., Container[T]]:

    def wrapper(*args: Any, **kwargs: Any) -> Container[T]:
        return Container(f(*args, **kwargs))

    return cast(Callable[..., Container[T]], wrapper)

@my_decorator
def my_func(i: int, s: str) -> bool: ...

reveal_type(my_func) # Revealed type is 'def (*Any, **Any) -> file.Container[builtins.bool*]

Which mypy sorcery is required to keep the argument types intact for my_func?

Using typing.Protocol looks promising, but I don't see how to make it work.

question from:https://stackoverflow.com/questions/65936408/typing-function-when-decorator-change-generic-return-type

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Using Callable[..., T] is currently the best way to annotate this.

PEP 612 introduces ParamSpec, which can be used similar to a TypeVar and will solve your problem. It's currently planned for Python 3.10 and will be supported for older versions using typing_extensions

There you would write:

T = TypeVar('T')
P = ParamSpec('P')

def my_decorator(f: Callable[P, T]) -> Callable[P, Container[T]]:

    def wrapper(*args: Any, **kwargs: Any) -> Container[T]:
        return Container(f(*args, **kwargs))

    return cast(Callable[P, Container[T]], wrapper)

mypy support for PEP 612 isn't finished yet: https://github.com/python/mypy/issues/8645. Same with pytype (Google's python typechecker).

pyright (Microsoft's python typechecker) and pyre (facebook's python typechecker) do already support PEP 612


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...