Python 3.6 has added Flag and IntFlag which support the usual bit-wise operations. As a bonus, the resulting values from the bit-wise operations are still members of the original flag class, and are singletons [1].

The aenum library also has this addition and is usable back to Python 2.7.

[1] A bug exists in 3.6.0: if the pseudo-flag members are being created in threads then there is no guarantee that you won't end up with duplicates; this is fixed in 3.6.1 (and never existed in aenum).

Answer from Ethan Furman on Stack Overflow
🌐
Python
docs.python.org › 3 › library › enum.html
enum — Support for enumerations
February 23, 2026 - For standard Enum classes the next value chosen is the highest value seen incremented by one. For Flag classes the next value chosen will be the next highest power-of-two.
Top answer
1 of 3
61

Python 3.6 has added Flag and IntFlag which support the usual bit-wise operations. As a bonus, the resulting values from the bit-wise operations are still members of the original flag class, and are singletons [1].

The aenum library also has this addition and is usable back to Python 2.7.

[1] A bug exists in 3.6.0: if the pseudo-flag members are being created in threads then there is no guarantee that you won't end up with duplicates; this is fixed in 3.6.1 (and never existed in aenum).

2 of 3
24

I've recently published an opensource package py-flags that aims this problem. That library has exactly this functionality and its design is heavily influenced by the python3 enum module.

There are debates about whether it is pythonic enough to implement such a flags class because its functionality has huge overlaps with other methods provided by the language (collection of bool variables, sets, objects with bool attributes or dicts with bool items, ...). For this reason I feel a flags class to be too narrow purpose and/or redundant to make its way to the standard library but in some cases it is much better than the previously listed solutions so having a "pip install"-able library can come in handy.

Your example would look like the following using the py-flags module:

from flags import Flags

class NetlistKind(Flags):
    Unknown = 0
    LatticeNetlist = 1
    QuartusNetlist = 2
    XSTNetlist = 4
    CoreGenNetlist = 8
    All = 15

The above things could be tweaked a bit further because a flags class declared with the library automatically provides two "virtual" flags: NetlistKind.no_flags and NetlistKind.all_flags. These make the already declared NetlistKind.Unknown and NetlistKind.All redundant so we could leave them out from the declaration but the problem is that no_flags and all_flags don't match your naming convention. To aid this we declare a flags base class in your project instead of flags.Flags and you will have to use that in the rest of your project:

from flags import Flags

class BaseFlags(Flags):
    __no_flags_name__ = 'Unknown'
    __all_flags_name__ = 'All'

Based on the previously declared base class that can be subclassed by any of your flags in your project we could change your flag declaration to:

class NetlistKind(BaseFlags):
    LatticeNetlist = 1
    QuartusNetlist = 2
    XSTNetlist = 4
    CoreGenNetlist = 8

This way NetlistKind.Unknown is automatically declared with a value of zero. NetlistKind.All is also there and it is automatically the combination of all of your declared flags. It is possible to iterate enum members with/without these virtual flags. You can also declare aliases (flags that have the same value as another previously declared flag).

As an alternative declaration using the "function-call style" (also provided by the standard enum module):

NetlistKind = BaseFlags('NetlistKind', ['LatticeNetlist', 'QuartusNetlist',
                                        'XSTNetlist', 'CoreGenNetlist'])

If a flags class declares some members then it is considered to be final. Trying to subclass it will result in error. It is semantically undesired to allow subclassing a flag class for the purpose of adding new members or change functionality.

Besides this the flags class provides the operators your listed (bool operators, in, iteration, etc...) in a type-safe way. I'm going to finish the README.rst along with a little plumbing on the package interface in the next few days but the basic functionality is already there and tested with quite good coverage.

Discussions

Automatically adding composite values to a Flag enum
The short version is that I have a Flag where every member (save one) should have a corresponding composite member of its value ORed with a special nonmember flag. Example: from enum import Flag, auto, nonmember # new… More on discuss.python.org
🌐 discuss.python.org
0
0
September 3, 2023
Iterating over `enum.Flag` types ignores zero-valued in Python 3.11
In Python 3.10, you can iterate over enum.Enum and enum.Flag types to yield their values. More on github.com
🌐 github.com
10
September 21, 2023
python - Representation of all values in Flag enum - Stack Overflow
I would like to have a "ALL" flag in my python Flags enum for which myenum.EVERY_MEMBER & myenum.ALL == myenum.EVERY_MEMBER holds true. I currently have: from enum import Flag, auto class More on stackoverflow.com
🌐 stackoverflow.com
Is there a reason why the python3 documentation doesn't advertise that enum Flags can be tested with 'in' and 'not in'?
It's hinted at in the doc though: Within an enumeration, the members can be compared by identity, and the enumeration itself can be iterated over. And the in/contains protocol says: For objects that don’t define __contains__(), the membership test first tries iteration via __iter__(), then the old sequence iteration protocol via __getitem__() It not being mentioned explicitly probably means that it's not recommended to do this. More on reddit.com
🌐 r/Python
14
4
July 27, 2022
🌐
Python documentation
docs.python.org › 3 › howto › enum.html
Enum HOWTO — Python 3.14.3 documentation
The default for Flag is STRICT, the default for IntFlag is EJECT, and the default for _convert_ is KEEP (see ssl.Options for an example of when KEEP is needed). Enums have a custom metaclass that affects many aspects of both derived Enum classes ...
🌐
Real Python
realpython.com › python-enum
Build Enumerations of Constants With Python's Enum – Real Python
December 15, 2024 - An enum in Python groups related constants in a single data type using the Enum class. You create enumerations by subclassing Enum or using the module’s functional API. Using Enum over simple constants provides structure, prevents reassignment, and enhances code readability. Enum, IntEnum, IntFlag, and Flag differ in their support for integer operations and bitwise flags.
🌐
Python.org
discuss.python.org › python help
Automatically adding composite values to a Flag enum - Python Help - Discussions on Python.org
September 3, 2023 - The short version is that I have a Flag where every member (save one) should have a corresponding composite member of its value ORed with a special nonmember flag. Example: from enum import Flag, auto, nonmember # new in 3.11 class Planet(Flag): _BIZARRO = nonmember(1) # flag to denote other version SUN = 0 # no bizarro version MERCURY = 2 # need to start with 2 to avoid _BIZARRO VENUS = auto() # auto works from here EARTH = auto() MARS = auto() BIZARRO_MER...
🌐
Readthedocs
pradyunsg-cpython-lutra-testing.readthedocs.io › en › latest › library › enum.html
enum — Support for enumerations - Python 3.12.0a0 documentation
_order_ – used in Python 2/3 code to ensure member order is consistent (class attribute, removed during class creation) _generate_next_value_ – used to get an appropriate value for an enum member; may be overridden ... For standard Enum classes the next value chosen is the last value seen incremented by one. For Flag classes the next value chosen will be the next highest power-of-two, regardless of the last value seen.
🌐
ArjanCodes
arjancodes.com › blog › python-enum-classes-for-managing-constants
Python Enums: Effective Constant Management Techniques | ArjanCodes
July 1, 2024 - IntFlag: A combination of IntEnum and Flag. IntEnum can be useful when you need enum members to behave like integers:
Find elsewhere
🌐
GitHub
github.com › python › cpython › issues › 109633
Iterating over `enum.Flag` types ignores zero-valued in Python 3.11 · Issue #109633 · python/cpython
September 21, 2023 - >>> import sys; print(sys.version) 3.10.12 | packaged by conda-forge | (main, Jun 23 2023, 22:40:32) [GCC 12.3.0] >>> import enum >>> class MyEnum(enum.Enum): ... A = 0 ... B = 1 ... C = 2 ... >>> list(MyEnum) [<MyEnum.A: 0>, <MyEnum.B: 1>, <MyEnum.C: 2>] >>> class MyFlag(enum.Flag): ... A = 0 ... B = 1 ... C = 2 ... >>> list(MyFlag) [<MyFlag.A: 0>, <MyFlag.B: 1>, <MyFlag.C: 2>] In Python 3.11, the same is true for enum.Enum types, but the behavior seems to have changed for enum.Flag types.
Author   gmgunter
🌐
AbyxDev's Blog
blog.abyx.dev › entries › 2022-06-23-enums-and-set-theory
Python Enum Flags and Basic Set Theory - AbyxDev's Blog
Flag instances do what Python sets cannot! Namely, the subclass defines the universe. Because of this, flag instances support the complement, in addition to other set operations: >>> class U(Flag): ... """Definition of the universe""" ... def __repr__(self) -> str: ... """Hide the unimportant numeric enum value.""" ...
🌐
GitHub
github.com › pydantic › pydantic › discussions › 3698
Treat enum.Flag and enum.IntFlag differently from Enums · pydantic/pydantic · Discussion #3698
match3 = MatchRequest(regex: 'a', string='abc', flags='2') # does now work because pydantic treats the Flag as an Enum value, instead of an int · this doesn't work not becouse of Pydantic but becouse of Python.
Author   pydantic
Top answer
1 of 5
12

There are a few ways to overcome this issue:

  • use a classproperty (see Zero's answer)

  • use a class decorator (see MSeifert's answer)

  • use a mixin (currently buggy)

  • create a new base class (see below)


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>
2 of 5
6

TL;DR Because property is only evaluated on instances of a class while the __members__ is only accessible on the class.


If you access a property on a class it just returns a property:

>>> RefreshFlags.ALL
<property at 0x2a5d93382c8>

To make this work however you need to either make it a classmethod:

from enum import Flag, auto

class RefreshFlags(Flag):
    NONE = 0
    EVENTS = auto()
    RESOURCES = auto()
    BUILDINGS = auto()
    DEFENSES = auto()

    @classmethod
    def ALL(cls):
        retval = self.NONE
        for member in cls.__members__.values():
            retval |= member
        return retval

>>> RefreshFlags.ALL()
<RefreshFlags.DEFENSES|BUILDINGS|RESOURCES|EVENTS: 15>

or access the property on an instance:

from enum import Flag, auto

class RefreshFlags(Flag):
    NONE = 0
    EVENTS = auto()
    RESOURCES = auto()
    BUILDINGS = auto()
    DEFENSES = auto()

    @property
    def ALL(self):
        retval = self.NONE
        # One needs to access .__class__ here!
        for member in self.__class__.__members__.values():
            retval |= member
        return retval

>>> RefreshFlags.EVENTS.ALL
<RefreshFlags.DEFENSES|BUILDINGS|RESOURCES|EVENTS: 15>

In both cases you can do your comparison later:

>>> RefreshFlags.EVENTS & RefreshFlags.EVENTS.ALL
<RefreshFlags.EVENTS: 1>

You stated in the comments that you want the ALL member to behave like the others, in that case I suggest using a class decorator:

def with_ALL_member(enumeration):
    retval = enumeration(0)  # in case NONE is not defined
    for name, member in enumeration.__members__.items():
        retval |= member
    enumeration.ALL = retval
    return enumeration

@with_ALL_member
class RefreshFlags(Flag):
    NONE = 0
    EVENTS = auto()
    RESOURCES = auto()
    BUILDINGS = auto()
    DEFENSES = auto()

>>> RefreshFlags.EVENTS & RefreshFlags.ALL
<RefreshFlags.EVENTS: 1>

>>> RefreshFlags.DEFENSES & RefreshFlags.ALL
<RefreshFlags.DEFENSES: 8>

The class decorator can also be used on other enums :)

🌐
Python
docs.python.org › 3.7 › library › enum.html
enum — Support for enumerations — Python 3.7.17 documentation
June 28, 2023 - The last variation is Flag. Like IntFlag, Flag members can be combined using the bitwise operators (&, |, ^, ~). Unlike IntFlag, they cannot be combined with, nor compared against, any other Flag enumeration, nor int.
🌐
Johnlekberg
johnlekberg.com › blog › 2020-06-06-enum.html
Using enumerated types in Python
for flag in Z80_Flag: if state & flag: status = "#" else: status = "." print(f"{flag.name:16} {status}") Carry . Subtract # Parity_Overflow # Half_Carry . Zero . Sign # Python supports four different types of enums via the enum module:
🌐
Zenva
gamedevacademy.org › home › python › a guide to using the python enum
A Guide To Using The Python Enum - GameDev Academy
January 22, 2024 - Adding a @unique decorator to the class, ensures that duplicate elements don’t exist in the Python enum. from enum import Enum, unique, Flag >> @unique ... class Months(Enum) : ... JANUARY=1 ... JANUARY=1 ... FEBRUARY=2 ... MARCH = 3 ... APRIL=4 ... MAY=5 ... JUNE=6 ...
🌐
DEV Community
dev.to › bjarnemagnussen › enum-vs-flag-for-bitmasks-in-python-2ig8
Enum vs Flag for bitmasks in Python - DEV Community
November 28, 2019 - Since Python 3.6 a class Flag exists for bit mask operations. >>> from enum import IntFlag, auto >>> >>> class Permissions(IntFlag): ... EXECUTE = auto() ... WRITE = auto() ... READ = auto() ... >>> class PermissionSet: ... def __init__(self, *flags): ... self._permission = Permissions(0) # Initiate no permissions ...
🌐
Reddit
reddit.com › r/python › is there a reason why the python3 documentation doesn't advertise that enum flags can be tested with 'in' and 'not in'?
r/Python on Reddit: Is there a reason why the python3 documentation doesn't advertise that enum Flags can be tested with 'in' and 'not in'?
July 27, 2022 -

I read the documentation at https://docs.python.org/3/library/enum.html

and in the section about 'Comparisons' they mentioned is and ==, which both don't work if your enum instance is a 'Flag' subclass and you're doing combinations.

ie:

from enum import Flag, auto
class Z(Flag):
     A = auto()
     B = auto()
     C = auto()
r = Z.A
r == Z.A #True
r is Z.A #True
Z.A is r #True
Z.A in r #True
r in Z.A #True

but...

r = Z.A | Z.B
r == Z.A #False
r is Z.A #False
Z.A is r #False
Z.A in r #True
Z.B in r #True
Z.C in r #False
r in Z.A #False
r in Z.B #False
r in Z.C #False

You'd expect the documentation would put the 'FLAG in enum_var' operation front and center because otherwise it's not very obvious how to use the Flag type, but not one mention of it.

You can also test flags you make yourself to other flags you make. Ex:

r = Z.A | Z.C
b = Z.A | Z.B
r in b #False
b in r #False
c = Z.B | Z.A
c in b #True
b in c #True
c = ZA.B | ZA.A | ZA.C
c in b #False
b in c #True
Top answer
1 of 3
5
It's hinted at in the doc though: Within an enumeration, the members can be compared by identity, and the enumeration itself can be iterated over. And the in/contains protocol says: For objects that don’t define __contains__(), the membership test first tries iteration via __iter__(), then the old sequence iteration protocol via __getitem__() It not being mentioned explicitly probably means that it's not recommended to do this.
2 of 3
1
Contains operator is just shorthand for "&==" pattern Line 879 The thinking is probably that: the &== pattern itself is well understood by anyone using a flag (its why they are using a flag) while the use of in is probably confusing for anyone not using a flag and unfamiliar with the concept and is arguably confusing for anyone familiar with a flag and how to use it. Ask someone who write C what O_RONLY in O_RW is supposed to be and they will give you some strange looks. I'm frankly a little surprised they even overrode __contains__ like this. Its too cute by half in my book. What is even stranger about this decision is that they while they overrode the contains operator, they didn't override . The bitwise operators on flags function identically as the same operators for sets. The former represents the set as bit-indicators, the latter explicitly realizes the set as a hash. If b'001' = Read = {read}, b'010' = write={write}, b'100' = execute={execute} then b'011' = Read|Write = {read, write} So obviously the test you want is "subset/superset". I want to know if Read|Write is a subset of user_permissions()... and we have an operator overload for poset comparison it is: <= and =>. So shouldn't it be: if (Read|Write) <= user_permissions(): Obviously the problem here is IntFlag and that most flags are built on ints. As a flag 3 < 4 is clearly false... but as an integer it is true. Probably all the more reason not to have exposed the IntFlag type. They aren't ints they are flags.
🌐
GitHub
github.com › python › cpython › issues › 67779
enum: Add Flags and IntFlags · Issue #67779 · python/cpython
March 5, 2015 - assignee = 'https://github.com/ethanfurman' closed_at = <Date 2016-11-21.16:31:14.558> created_at = <Date 2015-03-05.15:31:23.274> labels = ['type-feature', 'library'] title = 'enum: Add Flags and IntFlags' updated_at = <Date 2016-11-21.16:31:14.556> user = 'https://github.com/serhiy-storchaka' bugs.python.org fields: activity = <Date 2016-11-21.16:31:14.556> actor = 'python-dev' assignee = 'ethan.furman' closed = True closed_date = <Date 2016-11-21.16:31:14.558> closer = 'python-dev' components = ['Library (Lib)'] creation = <Date 2015-03-05.15:31:23.274> creator = 'serhiy.storchaka' dependen
Author   serhiy-storchaka
🌐
Python
docs.python.org › 3.11 › › howto › enum.html
Enum HOWTO — Python 3.11.14 documentation
March 14, 2019 - For standard Enum classes the next value chosen is the last value seen incremented by one. For Flag classes the next value chosen will be the next highest power-of-two, regardless of the last value seen.
🌐
GitHub
github.com › python › cpython › issues › 96865
Change in Flag enum behaviour in v3.11rc2 · Issue #96865 · python/cpython
September 16, 2022 - 3.11only security fixesonly security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory ... The following script... from enum import Flag class MethodHint(Flag): HiddenText = 0x10 DigitsOnly = 0x01 LettersOnly = 0x02 OnlyMask = 0x0f print(MethodHint.HiddenText|MethodHint.OnlyMask)
Author   philthompson10