Just to stop the bikeshedding, let's do #2. Put back __getitem__ solely for lookup by name. Keep __call__ (really __new__) for lookup by value or "pass-through" for members. --Guido On Fri, May 3, 2013 at 11:42 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
On Sat, May 4, 2013 at 4:10 PM, Georg Brandl <g.brandl@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@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@gmail.com | Brisbane, Australia _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/guido%40python.org
-- --Guido van Rossum (python.org/~guido)