pythonenumsauto

Extend python enum in __new__ with auto()


I have a question related to using auto() with python enum.

I have a base clase like this:

class TokenEnum(IntEnum):
    def __new__(cls, value):
        member = object.__new__(cls)

        # Always auto-generate the int enum value
        member._value_ = auto()  # << not working !!

        member.rule = value
        return member

and want to use it like this. The enum value should be an int and auto-generated. The string provided should go into the additional 'rule' variable.

class Tokens(TokenEnum):
    ID = r'[a-zA-Z_][a-zA-Z0-9_]*'
    ...

auto() doesn't seem to work in the place where I'm using it. And idea on how to get this working?


Solution

  • auto is resolved before __new__ is called -- it should only be used on the member assignment line (i.e. ID = auto()).

    If you need TokenEnum members to be integers, you'll want:

    def __new__(cls, value):
        int_value_ = len(cls.__members__) + 1   # numbering usually starts at 1
        member = int.__new__(cls, int_value)    # use int, not object
        member._value_ = int_value
        member.rule = value
        return member
    

    If they don't need to be integers, but you want the value to be an integer, you can do:

    def __new__(cls, value):
        int_value_ = len(cls.__members__) + 1   # numbering usually starts at 1
        member = object.__new__(cls)            # use object, not int
        member._value_ = int_value              # but assign the int value to _value_
        member.rule = value
        return member
    

    If you don't need the value to be an integer, but you do need the rule attribute:

    def __new__(cls, value):
        member = object.__new__(cls)            # use object, not int
        member._value_ = value
        member.rule = value
        return member
    

    Finally, if you want to just use the enum as if it were a string:

    class Tokens(str, Enum):
        ID = r'[a-zA-Z_][a-zA-Z0-9_]*'
    
    re.match(ID, some_target_string)
    

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