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

(🐞) [1.6 regression] Can not infer ParamSpec #16296

Closed
KotlinIsland opened this issue Oct 20, 2023 · 2 comments · Fixed by #16302
Closed

(🐞) [1.6 regression] Can not infer ParamSpec #16296

KotlinIsland opened this issue Oct 20, 2023 · 2 comments · Fixed by #16302
Labels
bug mypy got something wrong topic-paramspec PEP 612, ParamSpec, Concatenate

Comments

@KotlinIsland
Copy link
Contributor

KotlinIsland commented Oct 20, 2023

The function d takes two functions, an original, and a wrapper. The wrapper function needs to take the original function and its parameters.

Mypy is failing to infer the paramspec for the case where the wrapper indicates poisitional parameters. Unfortunately I'm too ignorant of the specifics of ParamSpec to know if this is working correctly or not 😢, but I would think that P would get inferred as [int]

@ilevkivskyi Can you provide any insight for this case?

FYI: This did not show an error in mypy 1.5.1, it inferred P as [i: int].

from collections.abc import Callable
from typing import Concatenate, _P as P

from mypy_extensions import Arg

def o(i: int) -> None:
    print(i)

def f1(c: Callable[[Arg(int, "i")], None], /, i: int) -> None:
    c(i)

def f2(c: Callable[[int], None], /, i: int) -> None:
    c(i)


def d(f: Callable[P, None], fn: Callable[Concatenate[Callable[P, None], P], None]) -> Callable[P, None]:
    def inner(*args: P.args, **kwargs: P.kwargs) -> None:
        fn(f, *args, **kwargs)
    return inner


d(o, f1) # works
d(o, f2)
# main.py:22: error: Cannot infer type argument 1 of "d"  [misc]
# main.py:22: error: Argument 1 to "d" has incompatible type "Callable[[Callable[[int], None], int], None]"; expected "Callable[[Callable[[VarArg(Any), KwArg(Any)], None], VarArg(Any), KwArg(Any)], None]"  [arg-type]
@KotlinIsland KotlinIsland added the bug mypy got something wrong label Oct 20, 2023
@KotlinIsland
Copy link
Contributor Author

Actually, I think a simplified version would be:

from collections.abc import Callable
from typing import Concatenate, _P as P

def f(c: Callable[[int], None], /, i: int) -> None:
    c(i)

def d(fn: Callable[Concatenate[Callable[P, None], P], None]) -> None:
    fn

d(f)
mypy 1.5.1: 
no error
mypy 1.6.1: 
main.py:10: error: Cannot infer type argument 1 of "d"  [misc]
main.py:10: error: Argument 1 to "d" has incompatible type "Callable[[Callable[[int], None], int], None]"; expected "Callable[[Callable[[VarArg(Any), KwArg(Any)], None], VarArg(Any), KwArg(Any)], None]"  [arg-type]

@AlexWaygood
Copy link
Member

Concentrating on the second example, since it's simpler -- I think this is a valid use of Concatenate (though it took me a little bit of time to get my head around it).

The second error doesn't seem to be reported if you use mypy master, but the first one is still there.

This bisects to 14418bc (cc. @ilevkivskyi).

hauntsaninja pushed a commit that referenced this issue Oct 23, 2023
Fixes #16296

In my big refactoring I flipped the variance convention for the
`Parameters` type, but I did it inconsistently in one place. After
working some more with ParamSpecs, it now seems to me the original
convention is easier to remember. I also now explicitly put it in the
type docstring.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-paramspec PEP 612, ParamSpec, Concatenate
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants