Skip to content

"Statement is unreachable" when doing match on type objects #18524

@woodruffw

Description

@woodruffw
Contributor

Hello mypy maintainers! I attempted to search for a dupe for this but couldn't find one, apologies if I missed it.

Bug Report

When running mypy with warn_unreachable = true (set in pyproject, but also on CLI), I get what appears to be a false positive for unreachable code on match statements where the matched object is a type and some of the arms are types.

For example (minimized/abstracted from my actual code):

import builtins
import typing
import types

def frobulate(field_type: type) -> str:
    match field_type:
        case builtins.int:
            ret = "foo"
        case builtins.str:
            ret = "foo"
        case builtins.bytes:
            ret = "foo"
        case builtins.bool:
            ret = "foo"
        case types.NoneType:
            ret = "foo"
        case _:
            return "bar"
            
    
    return ret

Produces:

main.py:10: error: Statement is unreachable  [unreachable]
main.py:12: error: Statement is unreachable  [unreachable]
main.py:16: error: Statement is unreachable  [unreachable]
Found 3 errors in 1 file (checked 1 source file)

However, at runtime, I can confirm that these case arms are matched correctly.

To Reproduce

Playground reproducer: https://mypy-play.net/?mypy=latest&python=3.13&flags=warn-unreachable&gist=416b0d53cd61032acee0341e9b24de11

(Note that --warn-unreachable needs to be enabled for reproduction. I think the Playground link should preserve this, but just in case!)

Expected Behavior

I expected mypy to match on type objects correctly, as Python itself appears to do correctly at runtime.

Actual Behavior

From above:

main.py:10: error: Statement is unreachable  [unreachable]
main.py:12: error: Statement is unreachable  [unreachable]
main.py:16: error: Statement is unreachable  [unreachable]
Found 3 errors in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: 1.14.1
  • Mypy command-line flags: --warn-unreachable
  • Mypy configuration options from mypy.ini (and other config files): N/A
  • Python version used: 3.13

Activity

sterliakov

sterliakov commented on Jan 24, 2025

@sterliakov
Collaborator

That's also type vs type[Any] issue. With type[Any] unreachable warnings are mostly gone, but the output is no better:

import builtins
import typing
import types

def frobulate(field_type: type[typing.Any]) -> str:
    match field_type:
        case builtins.int:
            reveal_type(field_type)
            ret = "foo"
        case builtins.str:
            reveal_type(field_type)
            ret = "foo"
        case builtins.bytes:
            reveal_type(field_type)
            ret = "foo"
        case builtins.bool:
            reveal_type(field_type)
            ret = "foo"
        case types.NoneType:
            reveal_type(field_type)
            ret = "foo"
        case _:
            reveal_type(field_type)
            return "bar"
             
    return ret
main.py:8: note: Revealed type is "type[Any]"
main.py:11: note: Revealed type is "Never"
main.py:14: note: Revealed type is "Never"
main.py:17: note: Revealed type is "type[builtins.bool]"
main.py:20: error: Statement is unreachable  [unreachable]
main.py:23: note: Revealed type is "type[builtins.bool]"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @woodruffw@A5rocks@sterliakov

        Issue actions

          "Statement is unreachable" when doing `match` on `type` objects · Issue #18524 · python/mypy