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

Enum exhaustiveness checking only works using "is" comparisons, not "==", conflicting with docs #14823

Closed
jonasrauber opened this issue Mar 3, 2023 · 1 comment
Labels
bug mypy got something wrong topic-enum

Comments

@jonasrauber
Copy link

The docs contain this example (simplified):

from enum import Enum
from typing_extensions import assert_never

class Direction(Enum):
    up = 'up'
    down = 'down'

def choose_direction(direction: Direction) -> None:
    if direction is Direction.up:
        print('Going up!')
        return
    elif direction is Direction.down:
        print('Down')
        return
    assert_never(direction)

This works. But if we switch to "==" for comparisons, it fails:

from enum import Enum
from typing_extensions import assert_never

class Direction(Enum):
    up = 'up'
    down = 'down'

def choose_direction(direction: Direction) -> None:
    if direction == Direction.up:
        print('Going up!')
        return
    elif direction == Direction.down:
        print('Down')
        return
    assert_never(direction)

error: Argument 1 to "assert_never" has incompatible type "Direction"; expected "NoReturn"

This is problematic, because the docs also have another example that uses == for comparison and implies that it would work if the second clause would be added.

def choose_direction(direction: Direction) -> None:
    if direction == Direction.up:
        print('Going up!')
        return
    assert_never(direction)  # E: Argument 1 to "assert_never" has incompatible type "Direction"; expected "NoReturn"

Beyond the docs, this is problematic, because we can have enums that subclass the value type, e.g.

class Direction(str, Enum):
    up = 'up'
    down = 'down'

Now it actually makes a difference at runtime whether we compare with is or ==, because == also matches normal strings 'up' and 'down', is does not.

Your Environment

Reproduced in Python 3.9 w/ typing_extensions and Python 3.11, using Mypy 1.0.1.

@jonasrauber jonasrauber added the bug mypy got something wrong label Mar 3, 2023
@hauntsaninja
Copy link
Collaborator

Yeah, I was annoyed by this too. I merged my PR that has been sitting around for a long time #11521

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
Projects
None yet
Development

No branches or pull requests

3 participants