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.