Python's enum is fine for naming constants and poor at giving them behaviour.
The moment a constant needs to do something, the logic lands in a branch
somewhere far away — an if status is CONFIRMED here, an elif there — until the
meaning of a constant is smeared across every file that touches it. As the
proposal puts it: understanding what CONFIRMED means requires reading every
file that branches on it — and when you add a new constant, the omissions are
silent.
Java solved this two decades ago: each enum constant can carry its own method
bodies. JEnum brings that to Python with two new base classes — DEnum
(Dispatch Enum) and MDEnum (Mutable Dispatch Enum) — where each constant is a
singleton that can override methods and carry its own fields.
class Operation(DEnum):
class PLUS(Operation):
def apply(self, x, y): return x + y
class MINUS(Operation):
def apply(self, x, y): return x - y
def apply(self, x, y): raise NotImplementedError
Operation.PLUS.apply(2, 3) # 5
The branching disappears. Behaviour lives on the constant, so adding TIMES is a
single contained change instead of a hunt through the codebase for every place
that switched on the operation.
The two flavours:
DEnum— immutable fields fixed at construction; the common case.MDEnum— controlled mutability for things that genuinely hold state, like state machines and device registries.
Both come with the conveniences you'd want: custom ordinals (map straight onto
HTTP codes or Unix signals), value_of() and from_ordinal(), comparison and
iteration, match/case pattern matching on 3.10+, several declaration styles,
and zero external dependencies.
JEnum is written up as a PEP draft — the aim is to land DEnum and MDEnum
in the standard library's enum module, with a working proof of concept that runs
back to Python 3.7.
- Repository: github.com/dvadura/JEnum
- PEP draft