Type narrowing is worse in a match statement on a tuple than the equivalent isinstance check.
With isinstance, mypy is able to determine that the type of a must be the tuple side of the union even though the check is only against Sequence, and then correctly narrows the type of the second element. With match, mypy is unable to do so and gives a union of the two element types in the tuple.
Hi! When you use isinstance(), it clearly narrows the type of int_a to int, and mypy recognizes this—so it doesn't return a warning. In contrast, match/case is more general, and type checkers like mypy are more conservative with pattern matching. As a result, mypy infers that int_a could be either a float or an int, and returns a type error.
Also, when I first ran your code, I didn't get a warning. I had to use mypy --strict repro.py to make the warning appear. Afterwards, I disabled strict mode by just running mypy repro.py, so those optional error checks were not enabled, and I didn’t receive the error again.
changed the title [-]Type narrowing for tuple worse with match than with the equivalent instanceof check[/-][+]Type narrowing for a tuple is worse with match than with the equivalent isinstance check[/+]on Jun 28, 2025
Activity
phoebecd commented on May 20, 2025
Hi! When you use isinstance(), it clearly narrows the type of int_a to int, and mypy recognizes this—so it doesn't return a warning. In contrast, match/case is more general, and type checkers like mypy are more conservative with pattern matching. As a result, mypy infers that int_a could be either a float or an int, and returns a type error.
Also, when I first ran your code, I didn't get a warning. I had to use mypy --strict repro.py to make the warning appear. Afterwards, I disabled strict mode by just running mypy repro.py, so those optional error checks were not enabled, and I didn’t receive the error again.
Jonas-Puksta-Sensmetry commented on Jun 26, 2025
I have bumped into the exact same issue, but in my case --strict flag is not needed to reproduce the problem.
From the code
Mypy produces error
main.py:4: error: Unsupported operand types for + ("str" and "int") [operator] main.py:4: note: Left operand is of type "str | int"(see https://mypy-play.net/?mypy=1.16.1&python=3.12&gist=920b90a2a8f48889b759b77935502820)
Jonas-Puksta-Sensmetry commented on Jun 26, 2025
A workaround is to replace <tupple-pattern> with tuple(<tupple-pattern>), like below
Mypy produces no errors for this code.
saulshanabrook commented on Aug 9, 2025
I just opened #19600 to fix this bug
Fix matching against union of tuples (python#19600)