Skip to content

[1.16 regression] determining exhaustive match on an enum with type members #19151

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

Closed
delfick opened this issue May 26, 2025 · 9 comments · Fixed by #19160
Closed

[1.16 regression] determining exhaustive match on an enum with type members #19151

delfick opened this issue May 26, 2025 · 9 comments · Fixed by #19160
Labels
bug mypy got something wrong topic-enum

Comments

@delfick
Copy link

delfick commented May 26, 2025

Hi,

I continued looking at how the codebase I work on responds to the upcoming mypy 1.16 release and I believe I found another bug

import datetime
import enum
from typing import assert_never


class ValueType(enum.Enum):
    BOOLEAN = bool
    DATE = datetime.date
    DATETIME = datetime.datetime


value_type: ValueType = ValueType.BOOLEAN

match value_type:
    case ValueType.BOOLEAN:
        pass
    case ValueType.DATE:
        pass
    case ValueType.DATETIME:
        pass
    case _:
        assert_never(value_type)

On mypy 1.16 I get this error

a.py:22: error: Argument 1 to "assert_never" has incompatible type "ValueType"; expected "Never"  [arg-type]

As far as I can tell this should be correct and I'm unsure why it doesn't think I have an exhaustive match.

Your Environment

  • Mypy version used: release-1.16 (revision 96525a2, built locally with mypy_mypyc-wheels for cp312-macosx_arm64)
  • Mypy command-line flags: mypy a.py
  • Mypy configuration options from mypy.ini (and other config files): no config
  • Python version used: python3.12
@delfick delfick added the bug mypy got something wrong label May 26, 2025
@delfick delfick changed the title Regression in upcoming mypy 1.16 Regression in upcoming mypy 1.16 - determining exhaustive match on an enum May 26, 2025
@hauntsaninja
Copy link
Collaborator

Thanks for testing pre-release. Bisects to #18675 cc @sobolevn

@vidhyavijayan3
Copy link

Hi @delfick @hauntsaninja

Can I work on this issue ?

@hauntsaninja
Copy link
Collaborator

Sure, please do. In general, don't need to ask, just put up PRs!

Obviously most principled thing to do is understand what enum actually does at runtime to differentiate the lambda case #18675 was thinking about. An ad hoc thing could be to special case type object function likes

@vidhyavijayan3
Copy link

Thanks for the go-ahead, @hauntsaninja! I’ll start digging into the issue and put up a PR as soon as I have a fix. I’ll also take a closer look at how enums behave at runtime to make sure the solution is solid. Appreciate the guidance!

@erictraut
Copy link

@vidhyavijayan3, there's one gotcha to keep in mind when you implement this. In general, enum types can be expanded into their individual literal member types. For example, the type ValueType is equivalent to Literal[ValueType.BOOLEAN, ValueType.DATE, ValueType.DATETIME] in the code sample above. This equivalency allows you to eliminate subtypes from the literal union based on pattern matches. However, this expansion doesn't work for classes that derive from enum.Flag, so this needs to be special-cased. For more details, refer to this section of the typing spec.

@vidhyavijayan3
Copy link

vidhyavijayan3 commented May 27, 2025

Thank you very much @erictraut for pointing that out. I understand the difference between enum and enum.Flag and the need to handle enum.Flag as a special case. I will review the relevant section of the typing specification to ensure I fully grasp the details before implementing the fix. I appreciate your helpful guidance!

@delfick

This comment has been minimized.

@hauntsaninja
Copy link
Collaborator

hauntsaninja commented May 28, 2025

Hmm that one bisects to #18972 , opened a new issue at #19159 for that!

@hauntsaninja hauntsaninja changed the title Regression in upcoming mypy 1.16 - determining exhaustive match on an enum [1.16 regression] determining exhaustive match on an enum with type members May 28, 2025
JukkaL added a commit that referenced this issue May 28, 2025
Type objects as enum values are supported at runtime.

Fixes #19151.
@JukkaL JukkaL closed this as completed in 568a638 May 28, 2025
@delfick
Copy link
Author

delfick commented May 28, 2025

Thanks for the fix @JukkaL ! I put that commit onto my local build of 1.16 and it worked great :)

JukkaL added a commit that referenced this issue May 29, 2025
Type objects as enum values are supported at runtime.

Fixes #19151.
cdce8p pushed a commit to cdce8p/mypy that referenced this issue May 31, 2025
Type objects as enum values are supported at runtime.

Fixes python#19151.
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

Successfully merging a pull request may close this issue.

5 participants