Is there a way to prevent specific `enum.Flag` combinations?

219 Views Asked by At

If I have an enum class like so:

class TestFlag(enum.Flag):
    A = enum.auto()
    B = enum.auto()
    C = enum.auto()
    D = A | B # valid

Is it possible to specify a certain combination, such as, say TestFlag.C | TestFlag.B as invalid? In other words, is there a way to ensure that writing TestFlag.C | TestFlag.B will raise an Error?

2

There are 2 best solutions below

4
Ethan Furman On BEST ANSWER

You could make use of the _missing_ method:

class TestFlag(enum.Flag):
    A = enum.auto()
    B = enum.auto()
    C = enum.auto()
    D = A | B # valid
    #
    def _missing_(self, value):
        if value in (5, 7):  # list of invalid values
            raise ValueError('%r is not a valid combination' % value)
        return super()._missing_(value)

NB: This will not catch invalid choices made during class creation, only operations that occur afterwards.


Disclosure: I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) library.

1
Frank Yellin On

You could add to your TestFlag class:

    def __or__(self, other):
        result = super().__or__(other)
        ... throw exception if result has some problem
        return result

I'm not sure I'd really recommend it, though.