python / python/mypy

Enum exhaustiveness checks fail with `@enum.member`-decorated members

Open
#18,722 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug topic-enum
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

Bug Report

Functions decorated with @enum.member are as rightful enum members as simple non-callable attributes.

Beware of #18721.

To Reproduce

from enum import Enum, member
from typing import assert_never

class E1(Enum):
    C = 1

def check_1(e: E1) -> None:
    match e:
        case E1.C:
            pass
        case other:
            assert_never(other)  # OK

    if e is E1.C:
        pass
    else:
        assert_never(e)  # OK


class E2(Enum):
    @member
    def C() -> None: ...  # E: Method must have at least one argument. Did you forget the "self" argument?  [misc]

def check_2(e: E2) -> None:
    match e:
        case E2.C:
            pass
        case other:
            assert_never(other)  # E: Argument 1 to "assert_never" has incompatible type "E2"; expected "Never"  [arg-type]

    if e is E2.C:
        pass
    else:
        assert_never(e)  # E: Argument 1 to "assert_never" has incompatible type "<subclass of "enum.member[Callable[[], None]]" and "__main__.E2">"; expected "Never"  [arg-type]

playground

Expected Behavior

Green output.

Actual Behavior

main.py:22: error: Method must have at least one argument. Did you forget the "self" argument?  [misc]
main.py:29: error: Argument 1 to "assert_never" has incompatible type "E2"; expected "Never"  [arg-type]
main.py:34: error: Argument 1 to "assert_never" has incompatible type "<subclass of "member" and "E2">"; expected "Never"  [arg-type]
Found 3 errors in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: 1.15.0 and current master
  • Mypy command-line flags: --strict and without
  • Mypy configuration options from mypy.ini (and other config files): N/A
  • Python version used: 3.12

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the provided Python 3.12 reproduction, with and without --strict, and compare it with the linked playground. Trace mypy's handling of @enum.member-decorated members and enum exhaustiveness checks. Done means the example produces no errors, including both assert_never calls and the decorated member definition.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.