4 Comments

If you really want the original signature with ParamSpec you can, but you need to use Concatenate and an intermediate higher-order function as well. Here is an example: https://gist.github.com/catwell/ca31fcd5e13f61bd6142d363b18df833

Expand full comment

Thanks Pierre!

AFAICT since you wrote `def g(url: str, *args: Any, **kwargs: Any) -> str:` you'll fall in the same trap, meaning calling `g` will not make mypy able to check the args passed to it.

Expand full comment

Sure, but will you never call g itself directly. You will call the result of _make_request which is properly typed.

And by the way, I used the name _make_request but if you have several functions where you need a version that wraps the first argument in a HttpClient you can reuse it for all of them even if they don't have the same signature.

You can even make it generic so it supports wrapping any type. I have added that version to the gist: https://gist.github.com/catwell/ca31fcd5e13f61bd6142d363b18df833#file-paramspec_wrapper_generic-py It is more complex but maybe it clarifies a bit more what this does. I have checked and it does work with both pyright and mypy: https://gist.github.com/catwell/ca31fcd5e13f61bd6142d363b18df833?permalink_comment_id=5460881#gistcomment-5460881

Expand full comment

Nice on! I just played a bit with it, and it works nicely. You just need to mark positional-only the arg list in some cases. Thanks for the intel, that's great to know there's a different way to do this, and it might be handy in some cases.

Expand full comment