Reputation: 725
def function(a: int, b: str) -> None:
pass
def wrapper(extra: int, *args, **kwargs) -> None:
do_something_with_extra(extra)
function(*args, **kwargs)
Is there an easy way for wrapper to inherit function()'s type hints without retyping all of them? Normally I'd write
def wrapper(extra: int, a: int, b: str) -> None:
But it becomes very verbose with a lot of arguments, and I have to update wrapper() every time I update function()'s arguments, and using *args, **kwargs
means there won't be proper autocomplete in vscode and other editors.
Upvotes: 11
Views: 2779
Reputation: 109
The best that you can do is to use a decorator for this purpose, and you can use Concatenate
and ParamSpec
. I use python 3.8 and I had to install typing_extensions
for them.
In the code below, if you type function in VSCode, it will show the int argument but without the "extra" name in front of it.
from typing import Callable, TypeVar
from typing_extensions import Concatenate, ParamSpec
P = ParamSpec('P')
R = TypeVar('R')
def wrapper(func: Callable[P, R]) -> Callable[Concatenate[int, P], R]:
def inner(extra, *args, **kwargs):
print(extra)
func(*args, **kwargs)
return inner
@wrapper
def function(a: int, b: str) -> None:
print(a, b)
pass
# typing function will show 'function: (int, a: int, b: str) -> None'
Upvotes: 6