You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A ParamSpec "captures" the signature of a callable. In the case of an overload, there are multiple signatures, so the rules for capture get complex and murky. PEP 612 doesn't provide any guidance about how ParamSpec and overload are supposed to interact. When I implemented support for ParamSpec in pyright, I decided not to support this combination. Pyright therefore emits an error message when attempting to use them together.
wrapper(Foo) # ParamSpec cannot be used with overloaded function
It looks like mypy also doesn't support the use of ParamSpec with an overload, but it doesn't emit an error message. An explicit error message should be easy to add and would provide clarity.
If there is demand for using ParamSpec in conjunction with overloaded functions, I recommend that we have a discussion in one of the typing forums and collectively think through the rules, expected behaviors, and edge cases.
If I’m using ParamSpec to parameterize arguments, then I probably don’t know in advance what kind of function I will be wrapping. Right? So it should be capable of representing all possibilities. Otherwise what’s the point of this?
FWIW, I think this is a reasonable feature request, though I can see that it might be... tricky to implement. I think Eric's input above is really valuable, but I'm not sure I see why this behaviour necessarily needs to be standardised across all type checkers in order for support to be added in mypy. I feel like it's probably in the purview of a type checker to optionally support additional features not explicitly covered by PEP 612.
But that's just my 2¢. Having a broader discussion, and standardising behaviour across type checkers, is obviously never a bad thing to do.
Activity
JelleZijlstra commentedon May 22, 2022
Is it possible to simplify this to an example that's independent from the stubs for list (https://github.com/python/typeshed/blob/6e18441a2c1e5836eca4e6763a9590d2b9270378/stdlib/builtins.pyi#L864)?
I suspect it has something to do with the overloaded
__init__; maybe mypy picks up only the first overload.AlexWaygood commentedon May 22, 2022
A workaround for this specific case is to use a
TypeVarbound toCallable[..., Any]instead ofParamSpec:(But this looks like a bug, for sure.)
AlexWaygood commentedon May 22, 2022
Here's a self-contained repro that doesn't reference the typeshed stub for
list:https://mypy-play.net/?mypy=latest&python=3.10&gist=1ef09e35aaa253c95d9165827c9add8f
markedwards commentedon May 22, 2022
Sure, I can avoid this by not using ParamSpec, but there are reasons I need ParamSpec. This is just a contrived example.
AlexWaygood commentedon May 22, 2022
I assumed so; just thought I'd mention it anyway :)
markedwards commentedon May 22, 2022
Incidentally, this works:
Not sure if that clarifies anything though.
AlexWaygood commentedon May 22, 2022
It looks like it's a bad interaction between
overloads andParamSpecthat causes the bug.erictraut commentedon May 22, 2022
A
ParamSpec"captures" the signature of a callable. In the case of an overload, there are multiple signatures, so the rules for capture get complex and murky. PEP 612 doesn't provide any guidance about howParamSpecandoverloadare supposed to interact. When I implemented support forParamSpecin pyright, I decided not to support this combination. Pyright therefore emits an error message when attempting to use them together.It looks like mypy also doesn't support the use of
ParamSpecwith an overload, but it doesn't emit an error message. An explicit error message should be easy to add and would provide clarity.If there is demand for using
ParamSpecin conjunction with overloaded functions, I recommend that we have a discussion in one of the typing forums and collectively think through the rules, expected behaviors, and edge cases.markedwards commentedon May 22, 2022
If I’m using ParamSpec to parameterize arguments, then I probably don’t know in advance what kind of function I will be wrapping. Right? So it should be capable of representing all possibilities. Otherwise what’s the point of this?
AlexWaygood commentedon May 22, 2022
FWIW, I think this is a reasonable feature request, though I can see that it might be... tricky to implement. I think Eric's input above is really valuable, but I'm not sure I see why this behaviour necessarily needs to be standardised across all type checkers in order for support to be added in mypy. I feel like it's probably in the purview of a type checker to optionally support additional features not explicitly covered by PEP 612.
But that's just my 2¢. Having a broader discussion, and standardising behaviour across type checkers, is obviously never a bad thing to do.
markedwards commentedon May 23, 2022
There are other variations of this issue.
With
tuple:With
iter:Basic support for decorated overloads (#15898)