I know of base classes Enum
and IntEnum
. Both are very helpful but I miss features for flag operations. I don't expect that these two classes implement my wished feature.
Let's construct an example:
class NetlistKind(IntEnum):
Unknown = 0
LatticeNetlist = 1
QuartusNetlist = 2
XSTNetlist = 4
CoreGenNetlist = 8
All = 15
As you can see, I'm already using IntEnum
to get arithmetic features for this enum. It would be nice to have something like @unique
to ensure all values are a power of two. I can do this by forking enum.unique for my needs. (I'm aware that All
is an exception from that rule.)
How is such an enum used?
filter = NetlistKind.LatticeNetlist | NetlistKind.QuartusNetlist
Thanks to the underlaying int bit operations are possible and filter has an internal value of 3.
If would be nice to have a "is flag X set in filter Y" function or even better an operator. I add a magic function for x in y
:
@unique
class NetlistKind(IntEnum):
Unknown = 0
LatticeNetlist = 1
QuartusNetlist = 2
XSTNetlist = 4
CoreGenNetlist = 8
All = 15
def __contains__(self, item):
return (self.value & item.value) == item.value
Usage example:
....
def GetNetlists(self, filter=NetlistKind.All):
for entity in self._entities:
for nl in entity.GetNetlists():
if (nl.kind in filter):
yield nl
def GetXilinxNetlists(self):
return self.GetNetlists(NetlistKind.XSTNetlist | NetlistKind.CoreGenNetlist)
So the questions are:
Open features:
__str__
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 psuedo-flag members are being created in threads then there may end up being duplicates; this is fixed in 3.6.1 (and never existed in aenum
).