There are a few ways to overcome this issue:
One thing to be aware of with the class property method is since the descriptor is defined on the class and not the metaclass the usual protections against setting and deleting are absent -- in other words:
>>> RefreshFlags.ALL <RefreshFlags.DEFENSES|BUILDINGS|RESOURCES|EVENTS: 15> >>> RefreshFlags.ALL = 'oops' >>> RefreshFlags.ALL 'oops'
Creating a new base class:
# lightly tested from enum import Flag, auto from operator import or_ as _or_ from functools import reduce class AllFlag(Flag): @classproperty def ALL(cls): cls_name = cls.__name__ if not len(cls): raise AttributeError('empty %s does not have an ALL value' % cls_name) value = cls(reduce(_or_, cls)) cls._member_map_['ALL'] = value return value
And in use:
class RefreshFlag(AllFlag): EVENTS = auto() RESOURCES = auto() BUILDINGS = auto() DEFENSES = auto() >>> RefreshFlag.ALL <RefreshFlag.DEFENSES|BUILDINGS|RESOURCES|EVENTS: 15>
The interesting difference in the ALL property is the setting of the name in _member_map_ -- this allows the same protections afforded to Enum members:
>>> RefreshFlag.ALL = 9 Traceback (most recent call last): .... AttributeError: Cannot reassign members.
However, there is a race condition here: if RefreshFlag.ALL = ... occurs before RefreshFlag.ALL is activated the first time then it is clobbered; for this reason I would use a decorator in this instance, as the decorator will process the Enum before it can be clobbered.
# lightly tested from enum import Flag, auto from operator import or_ as _or_ from functools import reduce def with_limits(enumeration): "add NONE and ALL psuedo-members to enumeration" none_mbr = enumeration(0) all_mbr = enumeration(reduce(_or_, enumeration)) enumeration.NONE = none_mbr enumeration.ALL = all_mbr enumeration._member_map_['NONE'] = none_mbr enumeration._member_map_['ALL'] = all_mbr return enumeration
And in use:
@with_limits class RefreshFlag(Flag): EVENTS = auto() RESOURCES = auto() BUILDINGS = auto() DEFENSES = auto() >>> RefreshFlag.ALL = 99 Traceback (most recent call last): ... AttributeError: Cannot reassign members. >>> RefreshFlag.ALL <RefreshFlag.DEFENSES|BUILDINGS|RESOURCES|EVENTS: 15> >>> RefreshFlag.NONE <RefreshFlag.0: 0>