[Python-Dev] AutoNumber Enum
Ethan Furman
ethan at stoneleaf.us
Wed Jun 29 15:23:32 EDT 2016
On 06/29/2016 12:11 PM, Guido van Rossum wrote:
> And how would you implement that without support from the compiler?
> Does it use a hook that catches the NameError?
It's built into the _EnumDict class dictionary used during class creation.
Current (edited) code from the aenum package that implements this:
class _EnumDict(dict):
"""Track enum member order and ensure member names are not reused.
EnumMeta will use the names found in self._member_names as the
enumeration member names.
"""
def __init__(self, locked=True, start=1, multivalue=False):
super(_EnumDict, self).__init__()
# list of enum members
self._member_names = []
# starting value for AutoNumber
self._value = start - 1
# when the magic turns off
self._locked = locked
...
def __getitem__(self, key):
if (
self._locked
or key in self
or _is_sunder(key)
or _is_dunder(key)
):
return super(_EnumDict, self).__getitem__(key)
try:
# try to generate the next value
value = self._value + 1
self.__setitem__(key, value)
return value
except:
# couldn't work the magic, report error
raise KeyError('%s not found' % key)
def __setitem__(self, key, value):
"""Changes anything not sundured, dundered, nor a descriptor.
Single underscore (sunder) names are reserved.
"""
if _is_sunder(key):
raise ValueError('_names_ are reserved for future Enum use')
elif _is_dunder(key):
if key == '__order__':
key = '_order_'
if _is_descriptor(value):
self._locked = True
elif key in self._member_names:
# descriptor overwriting an enum?
raise TypeError('Attempted to reuse name: %r' % key)
elif not _is_descriptor(value):
if key in self:
# enum overwriting a descriptor?
raise TypeError('%s already defined as: %r' % ...
self._member_names.append(key)
if not self._locked:
if isinstance(value, int):
self._value = value
else:
count = self._value + 1
self._value = count
value = count, value
else:
# not a new member, turn off the autoassign magic
self._locked = True
super(_EnumDict, self).__setitem__(key, value)
Disclaimer: some errors may have crept in as I deleted unrelated
content. For the full code check out the _EnumDict class in the aenum
package.
--
~Ethan~
More information about the Python-Dev
mailing list