Home > Mobile >  How to best check if Enum type is IntEnum or IntFlag
How to best check if Enum type is IntEnum or IntFlag

Time:11-10

My project has many Enums that follow a certain Naming convention.

I have a general method that converts a string into an Enum value.

I want to convert Enum Attribute Names to Enums ( I got this handled ).

Also I want to convert an int value passed in a string to an Enum if the enum inherits from IntEnum or IntFlag.

My question is as follows: Is there a better way to discover if ec is of type IntEnum or IntFlag?

def enum_from_string(s: str, ec: Type[Enum]) -> Enum:
    if not s:
        raise ValueError("from_str arg s cannot be an empty value")

    try:
        return getattr(ec, s.upper())
    except AttributeError:
        pass

    for t in ec.mro():
        if t is IntEnum or t is IntFlag:
            try:
                return ec(int(s))
            except ValueError:
                pass
            try:
                return ec(int(s, 16))
            except ValueError:
                pass
            break
    # finish processing and return value ...

Example usage:

class LayoutKind(IntEnum):
    TITLE_SUB = 0
    TITLE_BULLETS = 1
    TITLE_CHART = 2
    TITLE_2CONTENT = 3
    TITLE_CONTENT_CHART = 4

    @staticmethod
    def from_str(s: str) -> "LayoutKind":
        return kind_helper.enum_from_string(s, LayoutKind)

print(LayoutKind.from_str("3"))

CodePudding user response:

I think you just want:

if issubclass(ec, (enum.IntEnum, enum.IntFlag)):
    # handle IntEnum or IntFlag case

CodePudding user response:

I don't understand the entirety of your use-case, but here are some built-in enum capabilities:

from enum import IntEnum

class LayoutKind(IntEnum):
    TITLE_SUB = 0
    TITLE_BULLETS = 1
    TITLE_CHART = 2
    TITLE_2CONTENT = 3
    TITLE_CONTENT_CHART = 4
    #
    @classmethod
    def _missing_(cls, value):
        # called when no value match
        if not isinstance(value, str):
            return
        return cls(int(value))

and in use:

>>> LayoutKind['TITLE_SUB']
<LayoutKind.TITLE_SUB: 0>

>>> var = 'title_sub'
>>> LayoutKind[var.upper()]
<LayoutKind.TITLE_SUB: 0>

>>> LayoutKind(3)
<LayoutKind.TITLE_2CONTENT: 3>

>>> var = '3'
>>> LayoutKind(var)
<LayoutKind.TITLE_2CONTENT: 3>

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

  • Related