Is it possible to pass kwargs to customised python enum

Question:

You can customise an enum so the members have extra attributes.
There are plenty of examples of that to be found.
They all look something like this:

class EnumWithAttrs(Enum):
    def __new__(cls, *args, **kwargs):
        value = len(cls.__members__) + 1
        obj = object.__new__(cls)
        obj._value_ = value
        return obj
    def __init__(self, a, b):
        self.a = a
        self.b = b
    
    GREEN = 'a', 'b'
    BLUE = 'c', 'd'

this example is from https://stackoverflow.com/a/19300424/6439229

The majority of the examples I found show __new__ to accept kwargs, but is it actually syntactically possible to pass kwargs to __new__?

This gives SyntaxErrors:

class EnumWithAttrs(Enum):
    GREEN = 'a', foo='b'
    BLUE = 'c', **{'bar':  'd'}

So does this functional syntax:

Color = EnumWithAttrs('Color', [('GREEN', 'a', foo='b'), ('BLUE', 'c', **{'bar': 'd'})])

Do people put the **kwargs in the function def of __new__ just out of habit, or is there really a way to use them?

EDIT:
I’m not looking for a workaround to using kwargs, like passing a dict as a positional argument.

Asked By: mahkitah

||

Answers:

You could do

from enum import Enum


class EnumWithAttrs(Enum):
    def __new__(cls, *args, **kwargs):
        value = len(cls.__members__) + 1
        obj = object.__new__(cls)
        obj._value_ = value
        return obj

    def __init__(self, a, attrs):
        self.a = a
        self.attrs = attrs or {}


class AttributeyColor(EnumWithAttrs):
    GREEN = 'a', {'bar': 'b'}
    BLUE = 'c', {'glar': 'blarb'}


print(AttributeyColor.GREEN.attrs)

but this feels like abuse of Enums to me…

Answered By: AKX

Currently, there is no way to pass keyword args to an enum’s __new__ or __init__, although there may be one in the future.

The third-party library aenum1 does allow such arguments using its custom auto.


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

Answered By: Ethan Furman
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.