Repository navigation
[1.20 regression] value pattern match statement narrowing broken for typevars with values #21356
Description
Activity
- changed the title
[-]REGR: match statement builtins narrowing in 1.20[/-][+]REGR: match statement narrowing with typevars in 1.20[/+]on Apr 28, 2026 - changed the title
[-]REGR: match statement narrowing with typevars in 1.20[/-][+]REGR: value pattern match statement narrowing with typevars in 1.20[/+]on Apr 28, 2026 Thanks, I notice this only happens when
--warn-unreachableis not set. Setting--warn-unreachablegives the old expected behavior: https://mypy-play.net/?mypy=1.20.2&python=3.12&gist=c9f38f7eb2f7fb045aad1ecc5cb42cbb&flags=warn-unreachable. I guess something went wrong with how we're treating unreachable blocks when checking constrained typevar cases.- addedtopic-reachabilityDetecting unreachable codeDetecting unreachable code
on Apr 28, 2026 Bisects to #20146, cc @sterliakov
Reacted by Stanislav Terliakov- changed the title
[-]REGR: value pattern match statement narrowing with typevars in 1.20[/-][+][1.20 regression] value pattern match statement narrowing broken for typevars with values[/+]on Apr 28, 2026 Oh, interesting case...
So #20146 is a correct change. It make mypy's match narrowing use the same code paths as its equality narrowing. This makes mypy match Python semantics better.
Unfortunately, that means it is also a bit of an all-or-nothing change... differences between the equality narrowing logic and the (incorrect) logic mypy used to use for match narrowing, can show up as regressions like this one.
But fortunately, I spent a lot of time improving equality narrowing in the last release, which is where the
--warn-unreachablecomes into play. #20660 makes mypy's reachability logic a little stricter when--warn-unreachableis set. This happens to solve your false positive because of how mypy's logic for constrained type variables works.Ideally, I would like for this reachability logic to not depend on
--warn-unreachable. But as I mention in that PR, and as based on mypy_primer results, we need to make mypy check unreachable code for this to be a good idea.So I'm not quite sure how best to help you. If
--warn-unreachableis usable for you, that is great. Otherwise, we might just have to wait for changes to make mypy check unreachable code.Thanks for the reply! Appreciate this is all super complicated and sometimes there is a price in pushing things forward - and I'm very glad to see continual improvement in mypy. I think in our case we can migrate to warn unreachable so that should work well enough for us.
- addedtopic-match-statementPython 3.10's match statementPython 3.10's match statement
on May 1, 2026
Bug Report
I think I've found a regression in 1.20 - was recently trying to migrate a larger codebase from 1.18 and noticed this issue in a few places which didn't make sense. I've isolated it down to a small example which is a bit silly, but hopefully clear. I think this is a consequence of a deliberate change in #20908. Happy to try and put together a PR to resolve if useful, but I'm not exactly across the mypy internals, so might need a bit of guidance.
To Reproduce
https://mypy-play.net/?mypy=1.20.2&python=3.12&gist=ae5055b7e174f0ffd34db390a192aef5
Expected Behavior
Expected there to be no issues
Actual Behavior
edit: I did a bit more testing, there's nothing special about builtins here, but it needs to be a value pattern and not a class pattern for this example to even work in 1.19
Your Environment
mypy.ini(and other config files): None in minimal example