Python 3 - comparing enums against hex value

1

as newbie to python and hex based enums, I'm trying to wrap my head around something. My scenario is that I have a device that is sending me flags and I'm trying to determine which flags are set. I'm using python 3.7.

I've play around with the Python enum(Flag) class and can't seem to get it working. In the example below, I simulated a response of a status of "Running" and on "External Power".

from enum import Flag

class device_flags(Flag):
    RUNNING = (0x00000001)
    STOPPED = (0x00000004)
    PAUSED = (0x00000200)
    BAT_POWER = (0x01000000)
    EXT_POWER = (0x10000000)


device_status_flag = (0x10000001)  # simulate a response from device
print(device_status_flag in device_flags)

for flag in device_flags:
    print('{:15} = {}'.format(flag.name, device_status_flag in flag))

From what I've read, I would expect this to return true but I'm getting false(s):

(run results...)

False
RUNNING         = False
STOPPED         = False
PAUSED          = False
BAT_POWER       = False
EXT_POWER       = False

Does someone explain where I've gone wrong? (

I'm also getting a Deprecation Warning

"using non-Enums in containment checks will raise TypeError in Python 3.8"

--- How should I be comparing this?

python
python-3.x
asked on Stack Overflow May 7, 2019 by Kip

1 Answer

2

If you're strictly working with Flag objects, something like this:

def main():

    from enum import Flag

    class DeviceFlag(Flag):
        Running = 0x1
        Stopped = 0x2
        ExternalPower = 0x4

    input_status = DeviceFlag.Running | DeviceFlag.ExternalPower

    for flag in DeviceFlag:
        name = flag.name
        is_set = bool(flag & input_status)
        print(f"{name}: {is_set}")

    return 0

if __name__ == "__main__":
    from sys import exit
    exit(main())

Output:

Running: True
Stopped: False
ExternalPower: True

However, it sounds like you really do need to work with integers (hex values) since your flags are coming from an external device. In that case you'll have to use an IntFlag instead (an IntFlag inherits from int which allows you to compare it with integers):

def main():

    from enum import IntFlag

    class DeviceFlag(IntFlag):
        Running = 0x1
        Stopped = 0x2
        ExternalPower = 0x4

    # input_status = 0x5
    input_status = 0b101

    for flag in DeviceFlag:
        name = flag.name
        is_set = bool(flag & input_status)
        print(f"{name}: {is_set}")

    return 0

if __name__ == "__main__":
    from sys import exit
    exit(main())
answered on Stack Overflow May 7, 2019 by user10987432 • edited May 7, 2019 by user10987432

User contributions licensed under CC BY-SA 3.0