Need help with typing a decorator that can work on both regular functions and methods. #1222
Unanswered
vamshiaruru-virgodesigns
asked this question in
Q&A
Replies: 1 comment
-
Hello! I'm sorry about you having to wait for answer this long, hope it still will be useful. There are two issues in the snippet:
So, to fix that we need:
So it will be something like: import functools
from typing import Union, overload, Callable, TypeVar, Optional, Union, Protocol
from typing_extensions import Concatenate, ParamSpec
P = ParamSpec("P")
R = TypeVar("R")
Self = TypeVar("Self")
class Client:
...
class ClientInjector(Protocol):
@overload
def __call__(self, _: Callable[Concatenate[Self, Client, P], R], /) -> Callable[Concatenate[Self, P], R]:
...
@overload
def __call__(self, _: Callable[Concatenate[Client, P], R], /) -> Callable[P, R]:
...
def __call__(self, _: Callable) -> Callable:
...
def inject_client(
url: Optional[str] =None,
auth_token: Optional[str] = None
) -> ClientInjector:
def wrap(function):
@functools.wraps(function)
async def wrapper(*args, **kwargs):
async with Client(url, auth_token) as client:
return await function(client=client, *args, **kwargs)
return wrapper
return wrap # type: ignore
class Test:
@inject_client()
def test(self, client: Client):
...
@inject_client()
def testing(client: Client):
pass
reveal_type(Test.test)
reveal_type(testing) https://mypy-play.net/?mypy=latest&python=3.10&gist=bed0501ec912ca17a6bad96c0d49bfd3 |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hi all, I am trying to type a decorator that adds an additional functional argument using ParamSpec, and Concatenate. I am able to get it working for regular functions, but that same type hint doesn't work for method. I can get it working for a class method as well, but in that case it won't work for regular functions. Is there a way to get it working for both? Example below:
The above works when used on a method like so:
But when I use it on regular functions like this:
I get the error from pyright:
Any help is appreciated. TIA :)
Beta Was this translation helpful? Give feedback.
All reactions