Skip to content

Match involving unpacked tuple incorrectly marked unreachable #17095

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
JelleZijlstra opened this issue Apr 4, 2024 · 2 comments · Fixed by #18448
Closed

Match involving unpacked tuple incorrectly marked unreachable #17095

JelleZijlstra opened this issue Apr 4, 2024 · 2 comments · Fixed by #18448
Labels
bug mypy got something wrong topic-match-statement Python 3.10's match statement topic-pep-646 PEP 646 (TypeVarTuple, Unpack) topic-reachability Detecting unreachable code

Comments

@JelleZijlstra
Copy link
Member

def f(x: tuple[int, str, *tuple[range, ...]]) -> None:
    match x:
        case [1, *ts]:
            reveal_type(ts)

(Playground)

Produces no output, and with --warn-unreachable on says that line 4 is unreachable. But it's not unreachable; the case can match.

For comparison, pyright does not think the clause is unreachable but deduces an incorrect type (microsoft/pyright#7613).

@JelleZijlstra JelleZijlstra added bug mypy got something wrong topic-match-statement Python 3.10's match statement topic-reachability Detecting unreachable code topic-pep-646 PEP 646 (TypeVarTuple, Unpack) labels Apr 4, 2024
@randolf-scholz
Copy link
Contributor

randolf-scholz commented Apr 18, 2024

Here's another instance I noticed:

https://mypy-play.net/?mypy=latest&python=3.11&flags=warn-unreachable&gist=415990466cbd7bf9c78c6d7f71bebfd0

pyright-playground reports no issues.

from typing import overload, Any, Sequence

def foo(axis: Any):
    match axis:
        case None:
            return None
        case []:
            return ()  # ❌ Unreachable
        case int(a):
            return (a,)
        case _:
            return tuple(axis)
            
def bar(axis: Any):
    if axis is None:
        return None
    if isinstance(axis, Sequence) and len(axis)==0:
        return ()  # ✅ not considered unreachable
    if isinstance(axis, int):
        return (axis,)
    return tuple(axis)

@sterliakov
Copy link
Collaborator

The original problem no longer reproduces on latest 1.14.1, but the next snippet is still broken and thinks that empty sequence is unreachable.

hauntsaninja pushed a commit that referenced this issue Jan 13, 2025
Fixes #17095 (comment, the primary issue was already fixed somewhere
before). Fixes #16272. Fixes #12532. Fixes #12770.

Prior to this PR mypy did not consider that `Any` can match any
patterns, including sequence patterns (e.g. `case [_]`). This PR allows
matching `Any` against any such patterns.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-match-statement Python 3.10's match statement topic-pep-646 PEP 646 (TypeVarTuple, Unpack) topic-reachability Detecting unreachable code
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants