Falsey Enums

Ethan Furman ethan at stoneleaf.us
Fri Jul 28 10:24:24 EDT 2017


On 07/28/2017 01:13 AM, Ben Finney wrote:
> Ethan Furman writes:

>> class X(Enum):
>>      Falsey = 0
>>      Truthy = 1
>>      Fakey = 2
>>      def __bool__(self):
>>          return bool(self.value)
>
> I am surprised this is not already the behaviour of an Enum class,
> without overriding the ‘__bool__’ method.
>
> What would be a good reason not to have this behaviour by default for
> ‘Enum.__bool__’? (i.e. if this were reported as a bug on the ‘enum.Enum’
> implementation, what would be good reasons not to fix it?)

It matches the docs. ;)

   https://docs.python.org/3/library/enum.html#boolean-value-of-enum-classes-and-members

   Enum members that are mixed with non-Enum types (such as int, str, etc.)
   are evaluated according to the mixed-in type’s rules; otherwise, all
   members evaluate as True. To make your own Enum’s boolean evaluation
   depend on the member’s value add the following to your class:

   Enum classes always evaluate as True.

The rationale is in PEP 435, in the functional API section.

   The reason for defaulting to 1 as the starting number and not 0 is that 0 is False
   in a boolean sense, but enum members all evaluate to True .


Which still begs the question of:  why?  According to memory, and as Rustom guessed, an Enum member is a thing, and all 
things in Python default to being True.  If `bool(thing) == False` is a desirable characteristic then extra steps must 
be taken.  Either:

- subclass a type that already has that characteristic, such as int or float, or
- add your own __bool__ method (__nonzero__ in Python 2)

Looked at another way:  The value attribute is just that -- an attribute.  Depending on the use-case that attribute can 
be irrelevant (which is why we have auto(), etc.), so by default Enum does not use the .value attribute in figuring out 
if a member is something vs nothing (or truthy vs falsey).

--
~Ethan~



More information about the Python-list mailing list