It looks like the values in AutoNumberEnum are consecutive integers 1,2,3,...
Have you considered an option (keyword argument) to change this to powers of two 1,2,4,8,...?

--
Ivan



On 29 June 2016 at 21:23, Ethan Furman <ethan@stoneleaf.us> wrote:
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~