Skip to content

Enum instance type ignored in match/case statements #13841

Open
@ianonavy

Description

@ianonavy

Bug Report

When using an enum instance instead of a class property in a case statement, the type checker appears to ignore type errors inside the case statement.

May be related to #11784, not sure.

To Reproduce

import enum


class FooClass(enum.Enum):
    FOO = "FOO"


foo_inst = FooClass.FOO
match foo_inst:
    case foo_inst.FOO:
        1 + "a"

Playground link

Expected Behavior

I expected a type error on line 11, error: Unsupported operand types for + ("int" and "str"). My reasoning is that in cPython 3.10.7, FooClass.FOO and foo_inst.FOO both refer to the same object with the same id and should therefore have the same type checking behavior.

Actual Behavior

If you run mypy:

Success: no issues found in 1 source file

If you run it with python, you get a runtime TypeError even though the type checker failed to catch it.

The expected behavior occurs if you use the class name instead of the instance name:

import enum


class FooClass(enum.Enum):
    FOO = "FOO"


foo_inst = FooClass.FOO
match foo_inst:
    case FooClass.FOO:
        1 + "a"

Your Environment

  • Mypy version used: 0.982
  • Mypy command-line flags: none; same issue with --strict
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.10.7

More Details

More detailed investigation here

I tried to reveal_type to debug, and I got different values depending on the environment. With the mypy CLI against the following example and mypy Playground, I get the following:

import enum


class FooClass(enum.Enum):
    FOO = "FOO"


foo_inst = FooClass.FOO
match foo_inst:
    case FooClass.FOO:
        reveal_type(FooClass.FOO)
        reveal_type(foo_inst)
        reveal_type(foo_inst.FOO)
        1 + "a"
main.py:11: note: Revealed type is "Literal[__main__.FooClass.FOO]?"
main.py:12: note: Revealed type is "__main__.FooClass"
main.py:13: note: Revealed type is "Literal['FOO']?"
main.py:14: error: Unsupported operand types for + ("int" and "str")
Found 1 error in 1 file (checked 1 source file)

If I change line 10 to foo_inst.FOO, I get no revealed types at all: playground link.

Further, Visual Studio Code's bulit-in diagnostics seem to interpret the types for all three expressions as "Literal[FooClass.FOO]"

screenshot of Visual Studio Code showing the problems panel with messages that corroborate the above description

Curiously, the type checking seems to work when using an IntEnum instead of an Enum: playground link.

import enum


class FooClass(enum.IntEnum):
    FOO = 0


foo_inst = FooClass.FOO
match foo_inst:
    case foo_inst.FOO:
        reveal_type(FooClass.FOO)
        reveal_type(foo_inst)
        reveal_type(foo_inst.FOO)
        1 + "a"
main.py:11: note: Revealed type is "Literal[__main__.FooClass.FOO]?"
main.py:12: note: Revealed type is "<nothing>"
main.py:13: error: <nothing> has no attribute "FOO"
main.py:13: note: Revealed type is "Any"
main.py:14: error: Unsupported operand types for + ("int" and "str")
Found 2 errors in 1 file (checked 1 source file)

I also observe the expected behavior with if statements, so I think the issue is particular to the intersection of case and enum instance.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions