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 of myarg, which is FooP 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.
VSCode/Pylance has good support for this (since this data is taken directly from Pyright):

PyCharm, not so much:

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With