Opened 4 years ago

#8074 defect new

FlagConstants incorrectly remembers zero-valued flags.

Reported by: Cory Benfield Owned by:
Priority: normal Milestone:
Component: core Keywords:
Cc: Branch:
Author:

Description

Originally encountered as part of work on #7860.

When using FlagConstants, it is tempting to want to define a Flag to represent that absence of other flags. This allows for initialising a field at some kind of null value. With FlagConstants, the tempting way to do that is by doing:

class MyFlags(Flags):
    NULL = FlagConstant(0x0000)
    SOMEVAL = FlagConstant(0x0001)

If this behaved as expected, the logic would work like this:

>>> x = MyFlags.NULL
>>> x
<MyFlags=NULL>
>>> x |= MyFlags.SOMEVAL
>>> x
<MyFlags=SOMEVAL>

This is because, after ORing in SOMEVAL, the *numerical* value of the flag is 0x0001, which is equivalent to only having set SOMEVAL.

However, this is what *actually* happens:

>>> x = MyFlags.NULL
>>> x
<MyFlags=NULL>
>>> x |= MyFlags.SOMEVAL
>>> x
<MyFlags={NULL,SOMEVAL}>
>>> x == MyFlags.SOMEVAL
False

Essentially, the class "remembers" that it was initialised via the null value. It therefore compares unequal to one that was not initialised via that null value. This is surprising behaviour, because it breaks the illusion that FlagConstants is just a helpful representation of a bitmask.

Change History (0)

Note: See TracTickets for help on using tickets.