[Python-Dev] enum discussion: can someone please summarize open issues?

Nick Coghlan ncoghlan at gmail.com
Sat May 4 08:42:08 CEST 2013


On Sat, May 4, 2013 at 4:10 PM, Georg Brandl <g.brandl at gmx.net> wrote:
> Am 04.05.2013 01:22, schrieb Antoine Pitrou:
>> On Sat, 04 May 2013 11:15:17 +1200
>> Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
>>> Eli Bendersky wrote:
>>> > I'm just curious what it is about enums that sets everyone on a "let's
>>> > make things safer" path. Python is about duck typing, it's absolutely
>>> > "unsafe" in the static typing sense, in the most fundamental ways
>>> > imaginable.
>>>
>>> This isn't about catching bugs in the program, it's
>>> about validating user input. That's a common enough
>>> task that it deserves to have a convenient way to
>>> do it correctly.
>>
>> +1. An enum is basically a bidirectional mapping between some raw
>> values and some "nice" instances, so it deserves a well-defined lookup
>> operation in each direction.

As I see it, there are 3 possible ways forward here:

1. The current PEP, offering only "getattr(MyEnum, name)".

If code needs to ensure non-enum values are detected immediately (such
as during translation of user input entered at a command prompt), then
they can either create a separate mapping using:

    lookup = {m.name, m for m in (getattr(MyEnum, name) for name in
dir(MyEnum)) if isinstance(m, MyEnum)}

or else create a lookup function:

    def getmember(enum, name):
        m = getattr(enum, name, None)
        if not isinstance(m, enum):
            raise KeyError("{!r} is not a member of {!r}".format(name, enum))
        return m

2. We restore __getitem__ on EnumMetaclass *solely* for member lookup
by name (the "getmember" functionality above). This would leave
__call__ used for the reverse lookup (value to member and hence name)
and __getitem__ for the forward lookup (name to member and hence
value) (Note: given Ethan's comments about his current implementation,
I believe this actually fits nicely with the way
EnumMetaclass.__getattr__ is already implemented)

3. We offer my earlier suggestion of an "as_dict()" method on the
metaclass, which implements the mapping calculation above. As others
pointed out, this has the same name clash problem as offering
additional non-special methods on namedtuple objects.

I'm now -1 on my own as_dict() suggestion, due to the general name
clash problem for arbitrary enums.

Options 1 and 2 both sound reasonable to me, although I have a
preference for 2 due to the ability to produce a more appropriate
error message when the lookup fails.

Cheers,
Nick.

--
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-Dev mailing list