[Python] Why does MyPy fail to narrow types when comparing Enum members in this way?

Discussão em 'Python' iniciado por Stack, Agosto 8, 2025.

  1. Stack

    Stack Membro Participativo

    Given a simple enumerator:

    from enum import Enum
    from typing import assert_never

    class Day(Enum):
    MONDAY = 1
    TUESDAY = 2
    WEDNESDAY = 3


    And some code that handles members:

    a_day = Day(1) # simplified version of larger code base
    if a_day == a_day.MONDAY:
    print("MONDAY")
    elif a_day == a_day.TUESDAY:
    print("TUESDAY")
    elif a_day == a_day.WEDNESDAY:
    print("WEDNESDAY")
    else:
    assert_never(a_day)
    # MyPy revealed type is "Day", but linter revealed type is "Never"


    MyPy complains that assert_never is reachable.

    I'm expecting MyPy to understand that a_day is Never here. The linter does.

    I know that I can change it to:

    a_day = Day(1) # simplified version of larger code base
    if a_day == Day.MONDAY:
    print("MONDAY")
    elif a_day == Day.TUESDAY:
    print("TUESDAY")
    elif a_day == Day.WEDNESDAY:
    print("WEDNESDAY")
    else:
    assert_never(a_day)
    # MyPy revealed type is "Never"


    However, i'm trying to avoid referring to the Enum class directly ("Day"), as this causes issues whenever I use iPython with Autoreload: the instance "a_day" becomes a different type to Day after reloading from a separate module.

    I'm aware that I can restart the Python kernel to resolve, but this is impractical in my use case (Python opens other software that takes a lot of time to restart). I'm also aware of %reset -f --aggressive in iPython would also resolve, but this breaks other functions in our code base too, and is also frustrating when we forget until after the code fails.

    I have found a "hacky workaround" (problem being to remember to do it):

    a_day = Day(1) # simplified version of larger code base
    enum_type = type(a_day)
    if a_day == enum_type.MONDAY:
    print("MONDAY")
    elif a_day == enum_type.TUESDAY:
    print("TUESDAY")
    elif a_day == enum_type.WEDNESDAY:
    print("WEDNESDAY")
    else:
    assert_never(a_day)
    # MyPy revealed type is "Never", and continues to work through iPython Autoreload

    Continue reading...

Compartilhe esta Página