python/mypy (original) (raw)

Bug Report

It looks like the enum plugin incorrectly assumes that __bool__ on enum literals will always return Literal[True], while this is the default behavior, it is not correct when someone explicitly overrides __bool__. Moreover this special casing is only applied to enum literals, but not the base enum type, which should behave the same as individual members.

To Reproduce

https://mypy-play.net/?mypy=master&python=3.12&gist=dc60c5c82ba6589e5f1d03654439b05e

import enum from typing import Any, Literal

class Foo(enum.Enum): X = 0

class Bar(enum.Enum): X = 0

def __bool__(self) -> Literal[False]:
    return False

def a(x: Any | Literal[Foo.X]): reveal_type(x) if x: reveal_type(x) else: reveal_type(x)

def b(x: Any | Foo): reveal_type(x) if x: reveal_type(x) else: reveal_type(x) # wrong, doesn't match literal behavior

def c(x: Any | Literal[Bar.X]): reveal_type(x) if x: reveal_type(x) # wrong, it's backwards else: reveal_type(x) # wrong, it's backwards

def d(x: Any | Bar): reveal_type(x) if x: reveal_type(x) else: reveal_type(x)

Your Environment