How to add Docstrings in Enum inside Dictionaries

Viewed 653

I use Enums inside dictionaries:

Parameters = {
    ONE: Enum(
        value = 'Options',
        names = [
            ('SEPARATE', 0b1),
            ('SEQUENTIAL', 0b0)
        ]
    )
}

This style work fits my needs perfectly.

However, when using Enums in a different way, I am able to add docstrings:

class ONE(Enum):
    SEPERATE = 0b1
    """The registers associated with each port are separated into different banks"""
    SEQUENTIAL = 0b0
    """The registers are in the same bank (addresses are sequential)"""

My question then:

How can I add docstrings when using Enums inside dictionaries as in the first example?

Update Testing enum

Parameters = {
    'ONE': Enum(
        value = 'ONE',
        names = [
            ('SEPARATE', 0b1),
            ('SEQUENTIAL', 0b0)
        ]
    )
}

print(Parameters['ONE'].SEPARATE)

Works as expected

Then attempted to extend Enum()

class NewEnum(Enum):
    def __init__(self, **kw):
        super(NewEnum, self).__init__(**kw)


Parameters = {
    'ONE': NewEnum(
        value = 'ONE',
        names = [
            ('SEPARATE', 0b1),
            ('SEQUENTIAL', 0b0)
        ]
    )
}

Does not work.

1 Answers

You aren't setting docstrings, you're writing comments:

>>> from enum import Enum
>>> class ONE(Enum):
...     SEPERATE = 0b1
...     """The registers associated with each port are separated into different banks"""
...     SEQUENTIAL = 0b0
...     """The registers are in the same bank (addresses are sequential)"""
... 
>>> ONE.SEPERATE.__doc__
'An enumeration.'

So, the easy way is to just add real comments:

Parameters = {
    ONE: Enum(
        value = 'Options',
        names = [
            ('SEPARATE', 0b1),   # The registers associated with each port are separated into different banks
            ('SEQUENTIAL', 0b0)  # The registers are in the same bank (addresses are sequential)
        ]
    )
}

Actually adding __doc__ using the type() format may be a bit harder -- I'll look into it.


Okay, here is the custom Enum, EnumWithDocstring:

class EnumWithDocstring(Enum):
    #
    def __new__(cls, value, doc=None):
        member = object.__new__(cls)
        member._value_ = value
        member.__doc__ = doc
        return member

There is nothing fancy going on with the new Enum; the tricky part is realizing that all values passed to the Enum constructor have to be a tuple, so your Parameters will look like:

Parameters = {
    'ONE': EnumWithDocstring(
        value = 'Options',
        names = [
            ('SEPARATE', (0b1, 'test docstring')),
            ('SEQUENTIAL', 0b0)
        ]
    )
}

SEPARATE has a docstring, but SEQUENTIAL does not.


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

Related