Skip to content
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

Enums with only one member do not exhaustively match correctly #14264

Closed
johnthagen opened this issue Dec 8, 2022 · 3 comments
Closed

Enums with only one member do not exhaustively match correctly #14264

johnthagen opened this issue Dec 8, 2022 · 3 comments
Labels
bug mypy got something wrong topic-enum topic-match-statement Python 3.10's match statement topic-reachability Detecting unreachable code

Comments

@johnthagen
Copy link
Contributor

Bug Report

Enums with only one member do not exhaustively match correctly.

To Reproduce

from enum import Enum, auto

from typing_extensions import assert_never


class Color(Enum):
    Red = auto()


def f(color: Color) -> None:
    match color:
        case Color.Red:
            print("red")
        case _ as unreachable:
            assert_never(unreachable)

Expected Behavior

No type checking errors.

Actual Behavior

$ mypy main.py
main.py:15: error: Argument 1 to "assert_never" has incompatible type "Color"; expected "NoReturn"  [arg-type]
Found 1 error in 1 file (checked 1 source file)

Your Environment

$ pip list
Package           Version
----------------- -------
mypy              0.991
mypy-extensions   0.4.3
pip               22.3.1
setuptools        65.6.3
tomli             2.0.1
typing_extensions 4.4.0
wheel             0.38.4
  • Mypy version used: 0.991
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.10.8

Additional Context

What's strange is that if the Enum has at least 2 members, everything works correctly:

from enum import Enum, auto

from typing_extensions import assert_never


class Color(Enum):
    Red = auto()
    Blue = auto()


def f(color: Color) -> None:
    match color:
        case Color.Red:
            print("red")
        case Color.Blue:
            print("blue")
        case _ as unreachable:
            assert_never(unreachable)
@johnthagen johnthagen added the bug mypy got something wrong label Dec 8, 2022
@AlexWaygood AlexWaygood added topic-enum topic-reachability Detecting unreachable code topic-match-statement Python 3.10's match statement labels Dec 8, 2022
@AlexWaygood
Copy link
Member

It looks like the bug is specific to pattern-matching; mypy has no problems with this version of the same function using if/else idioms (and it will correctly identify the else branch as unreachable if you add a call to reveal_type):

from enum import Enum, auto

from typing_extensions import assert_never


class Color(Enum):
    Red = auto()


def f(color: Color) -> None:
    if color is Color.Red:
        print("red")
    else:
        assert_never(color)

https://mypy-play.net/?mypy=latest&python=3.11&gist=ca293bc0ccb5ec9c77af029f0c95360e

@tmke8
Copy link
Contributor

tmke8 commented Dec 11, 2022

Same issue? #14109

@AlexWaygood
Copy link
Member

Same issue? #14109

Yup, thanks @thomkeh!

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-enum topic-match-statement Python 3.10's match statement topic-reachability Detecting unreachable code
Projects
None yet
Development

No branches or pull requests

3 participants