Use IntFlag to combine small capability bits
Also published in our Blogger archive.
IntFlag is useful when a value represents several independent, compact capability bits rather than one mutually exclusive state. Each member has one bit; | combines choices, and & extracts overlap. In this example, READ and EXPORT produce the integer mask 5. The assertions verify the expected bit relationships before the program reports the numeric mask and two capability checks.
Use names at the definition site instead of scattered numeric literals, but keep the bit allocation stable if masks cross a storage or API boundary. IntFlag members are also integers, so they can be passed to integer-oriented interfaces; ordinary arithmetic such as flag + 1 produces an int, not a flag value. This pattern also does not decide whether a caller should receive a capability: it only represents and tests a selected set.
IntFlag and auto() were added in Python 3.6. The official enum documentation describes IntFlag bitwise behavior and its integer compatibility.
AI-assistance disclosure: this article was drafted with AI assistance and should be adapted to the application’s authorization rules.
from enum import IntFlag, auto
class Capability(IntFlag):
READ = auto()
WRITE = auto()
EXPORT = auto()
selected = Capability.READ | Capability.EXPORT
assert selected == 5
assert bool(selected & Capability.READ)
assert not bool(selected & Capability.WRITE)
print(
f"mask={int(selected)} "
f"has_read={bool(selected & Capability.READ)} "
f"has_write={bool(selected & Capability.WRITE)}"
)
mask=5 has_read=True has_write=False