class Label(Enum): RedApple = 1 GreenApple = 2 @classmethod def _missing_(cls, name): for member in cls: if member.name.lower() == name.lower(): return member Currently, _missing_ is only called when using the functional API. In words: Label('redapple') # works Label.redapple # does not
Could that perhaps be intentional? Attribute access seems like something where the developer would be explicitly naming a single, hard coded, canonical name for the type, while string construction seems like something where you're getting a string from "somewhere" (user input, which is always terrible) and you'd want to have a way to handle invalid input. The documentation is so sparse as to be useless for determining intent: _missing_ – a lookup function used when a value is not found; may be overridden I wouldn't view Label.redapple as an attempt to "find" anything, it's just simple attribute access.
Thank you, Josh, that's a very good point. One can be expected to have the correct spelling when using attribute access. So the two accesses that make sense for a _missing_ call would then be: - by-value lookup (e.g. Label(1)) - by-name lookup (e.g. Label['redapple']) Sound reasonable?
To move this forward: The proposal is to add support for a new method, _missing_name_, which is called by __getitem__. If such a method does not exist, the normal AttributeError exception is raised; otherwise, the _missing_name_ method is called with the invalid name and should return a matching member or None; - if None, the normal AttributeError exception is raised - if a member, it is returned - otherwise, a Type(?)Error is raised
I'm not convinced this piece needs to be in the stdlib. Unlike other bits that need extensive metaclass support this is trivial to add: class DerivedEnumMeta(EnumMeta): def __getitem__(cls, name): try: return cls._member_map_[name] except KeyError: result = cls._missing_name_(name) if isinstance(result, cls): return result raise
History
Date
User
Action
Args
2022-04-11 14:58:44
admin
set
github: 73938
2018-01-22 07:47:09
ethan.furman
set
status: open -> closedversions: - Python 3.6messages: + resolution: rejectedstage: test needed -> resolved
2018-01-18 19:28:25
ethan.furman
set
messages: + title: Enum._missing_ not called for __getattr__ failures -> Enum._missing_ not called for __getitem__ failures