def foo(myarg, **other_args):
# do something
return bar(**other_args)
Is it possible to annotate this function in a way that would make it clear to IDEs that other_args
are the arguments of function bar()
? So that the IDE would provide a helpful code completion in this case.
Combine this answer with Concatenate
:
(playgrounds: Mypy, Pyright)
def same_signature_with_one_leading_extra[**P, T, E](
_origin: Callable[P, T]
) -> Callable[
[Callable[Concatenate[E, ...], Any]],
Callable[Concatenate[E, P], T]
]:
def decorator(target: Callable[Concatenate[E, ...], Any]) -> Callable[Concatenate[E, P], T]:
return cast(Callable[Concatenate[E, P], T], target)
return decorator
def bar(*, lorem: bool, ipsum: float = 3.14) -> None:
...
@same_signature_with_one_leading_extra(bar)
def foo(myarg: Foo, *args: Any, **kwargs: Any) -> Any:
return bar(**kwargs)
reveal_type(foo) # (Foo, *, lorem: bool, ipsum: float = 3.14) -> None
Note that Mypy requires myarg
to be positional-only (the /
):
@same_signature_with_one_leading_extra(bar)
def foo(myarg: Foo, /, *args: Any, **kwargs: Any) -> Any:
return bar(**kwargs)
Concatenate
prepends a type variable E
to the parameter specification P
. In context:
E
refers to the type ofmyarg
, which isFoo
P
refers to the signature of_origin
, which is(*, lorem: bool, ipsum: float = 3.14)
Concatenate[E, P]
is thus resolved to (Foo, *, lorem: bool, ipsum: float = 3.14)
. This, wrapped in Callable[<>, T]
, is used as the return type of the decorator and becomes the new type of foo
.
IDE support
VSCode/Pylance has good support for this (since this data is taken directly from Pyright):
PyCharm, not so much: