I'd like to give documentation for each member of a python enum in a way that IPython can find it. What I have right now is something like:
class Color(Enum):
    """
    RED: The color red
    GREEN: The color green
    BLUE: The color blue. These docstrings are more useful in the real example
    """
    RED = 1
    GREEN = 2
    BLUE = 3
This isn't great, as it duplicates the member names, and makes it harder to ask for the documentation for just one member.
I can get what I'm after with
class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3
Color.RED.__doc__ = "The color red"
Color.GREEN.__doc__ = "The color green"
Color.BLUE.__doc__ = "The color blue. These docstrings are more useful in the real example"
But this still suffers from repetition of the names.
Is there an easier way of doing this?
@Eric has shown how to do it using the stdlib Enum; this is how to do it using aenum1:
from aenum import Enum  # or IntEnum
class Color(Enum):                     # or IntEnum
    _init_ = 'value __doc__'
    RED = 1, 'The color red'
    GREEN = 2, 'The color green'
    BLUE = 3, 'The color blue'
1 Disclosure:  I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum)  library.
You can override Enum.__new__ to take a doc argument as follows:
class DocEnum(Enum):
    def __new__(cls, value, doc=None):
        self = object.__new__(cls)  # calling super().__new__(value) here would fail
        self._value_ = value
        if doc is not None:
            self.__doc__ = doc
        return self
Which can be used as:
class Color(DocEnum):
    """ Some colors """
    RED   = 1, "The color red"
    GREEN = 2, "The color green"
    BLUE  = 3, "The color blue. These docstrings are more useful in the real example"
Which in IPython, gives the following:
In [17]: Color.RED?
Type:            Color
String form:     Color.RED
Docstring:       The color red
Class docstring: Some colors
This can also be made to work for IntEnum:
class DocIntEnum(IntEnum):
    def __new__(cls, value, doc=None):
        self = int.__new__(cls, value)  # calling super().__new__(value) here would fail
        self._value_ = value
        if doc is not None:
            self.__doc__ = doc
        return self
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With