Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverse type inference for decorator ParamSpec #6989

Closed
kcajf opened this issue Feb 26, 2025 · 2 comments
Closed

Reverse type inference for decorator ParamSpec #6989

kcajf opened this issue Feb 26, 2025 · 2 comments
Assignees
Labels
needs repro Issue has not been reproduced yet

Comments

@kcajf
Copy link

kcajf commented Feb 26, 2025

This issue may be related to #4391 but I'm not sure.

I have a decorator that looks like this:

def my_decorator(*args, **kwargs):
    def inner(fn):
        do_something(fn(*args, **kwargs))
        return fn
    return inner

@my_decorator(1, y=2)
def func(x: int, y: int): ...

In other words, it is a decorator that accepts the same shape of arguments as the wrapped function, and calls the wrapped function with them before returning the original function. (The exact reason for wanting this is a bit involved, but for example could be used to globally register trace-precompilation of some jitted functions).

I can type this with a ParamSpec:

def do_stuff(x: Any): ...

def my_decorator[T, **P](*args: P.args, **kwargs: P.kwargs) -> Callable[[Callable[P, T]], Callable[P, T]]:
    def inner(fn: Callable[P, T]) -> Callable[P, T]:
        do_stuff(fn(*args, **kwargs))
        return fn
    return inner

@my_decorator(1, y=2)
def func(x: int, y: int): ...

but this doesn't work:

Image

This isn't surprising, because at the point of calling my_decorator, we don't yet know which function it is going to decorator.

I wonder if pylance could support such a reverse-type-inference for decorators?

@github-actions github-actions bot added the needs repro Issue has not been reproduced yet label Feb 26, 2025
@erictraut
Copy link
Contributor

Pyright (the type checker that pylance is based on) conforms to the Python typing spec. For details about how ParamSpec's work, please refer to this chapter.

What you are trying to do here isn't currently possible with the facilities in the typing spec.

If you'd like to propose new features for the Python type system, the process for amending or adding to the spec is documented here. A good starting place is to post to the Python typing forum with a description of the problem you're trying to solve plus (optionally) a proposed solution.

I don't see an obvious way to make ParamSpecs work in reverse like this, but maybe someone else on the forum will have some ideas.

@kcajf
Copy link
Author

kcajf commented Feb 26, 2025

Thanks Eric! I had no idea there was a spec for type inference - good to know. I'll ask the question over there.

@rchiodo rchiodo closed this as completed Feb 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs repro Issue has not been reproduced yet
Projects
None yet
Development

No branches or pull requests

3 participants