Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I attach documentation to members of a python enum?

Tags:

python

enums

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?

like image 781
Eric Avatar asked May 22 '18 18:05

Eric


2 Answers

@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.

like image 119
Ethan Furman Avatar answered Nov 09 '22 20:11

Ethan Furman


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
like image 31
Eric Avatar answered Nov 09 '22 20:11

Eric