mypy icon indicating copy to clipboard operation
mypy copied to clipboard

Untrue unreachable statements with list pattern matching

Open JanczarKurek opened this issue 2 years ago • 1 comments

Bug Report When trying to use pattern matching statements that contain list-type matches mypy emits bogus "unreachable" errors.

To Reproduce The following code

    from typing import Any

    def list_len(l: Any):
        match l:
            case []:
                return 0
            case [_]:
                return 1
            case _:
                return "Big number"

generates error

pattern_matching_mypy.py:6: error: Statement is unreachable  [unreachable]

when run with option --warn-unreachable. Curiously it is enough to hint at a possibility of l being a list by doing

    from typing import Any

    def list_len(l: Any | list):
        match l:
            case []:
                return 0
            case [_]:
                return 1
            case _:
                return "Big number"

to make the error disappear.

Expected Behavior Both snippets of code should emit no errors as it is clearly possible to match l if it is a list.

Actual Behavior The following error is generated

pattern_matching_mypy.py:6: error: Statement is unreachable  [unreachable]
pattern_matching_mypy.py:8: error: Statement is unreachable  [unreachable]

My Environment

  • Mypy version used: 1.3.0, 1.4.0, 1.6.0
  • Mypy command-line flags: --warn-unreachable
  • Python version used: 3.10.13, 3.11.5, 3.12.0

JanczarKurek avatar Oct 16 '23 18:10 JanczarKurek

I ran into this on 1.11 with:

from typing import Any

ruff: dict[str, Any] = {"src": ["src"], "other": True}
match ruff:
    case {"src": ["src"]}:
        print("got it!")

It's fine with dict[str, object], but the Any makes it unreachable.

henryiii avatar Aug 19 '24 22:08 henryiii