Incompatible ParamSpecs are not reported as issue
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Bug Report
Hey everyone, thanks for all the great work on mypy!
I ran into an issue where mypy does not warn if 2 ParamSpecs need to align but they don't. Hard to describe, so here's an example:
To Reproduce
from collections.abc import Callable
from typing import ParamSpec
P = ParamSpec("P")
def foo(cb1: Callable[P, None], cb2: Callable[P, None]) -> None:
pass
def my_callback_1(x: int) -> None:
pass
def my_callback_2(x: str) -> None:
pass
foo(my_callback_1, my_callback_2)
Playground link: https://mypy-play.net/?mypy=latest&python=3.12&flags=strict&gist=f2fac01dde7a953c5dec5117428350f6
Expected Behavior
I think mypy should error out on the foo() call since it's not possible to resolve both Callables to a common ParamSpec P.
When I put the same code into VSCode, pylance reports the following error:
Argument of type "(x: str) -> None" cannot be assigned to parameter "cb2" of type "(**P@foo) -> None" in function "foo"
Type "(x: str) -> None" is not assignable to type "(x: int) -> None"
Parameter 1: type "int" is incompatible with type "str"
"int" is not assignable to "str"
Pylance[reportArgumentType](https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportArgumentType)
Actual Behavior
mypy does not report any issues:
Success: no issues found in 1 source file
Your Environment
See the playground link above, but when I run into this locally, I have:
- Mypy version used:
mypy 1.11.2 (compiled: yes) - Mypy command-line flags:
--strict - Mypy configuration options from
mypy.ini(and other config files):None - Python version used:
Python 3.12.2
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the provided Python 3.12 reproducer with mypy 1.11.2 and strict mode, then trace how the type checker resolves the shared ParamSpec in the foo() call. Done means mypy reports the incompatible callback argument and has regression coverage for this example.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100