• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import sys
2from types import MappingProxyType, DynamicClassAttribute
3
4
5__all__ = [
6        'EnumMeta',
7        'Enum', 'IntEnum', 'Flag', 'IntFlag',
8        'auto', 'unique',
9        ]
10
11
12def _is_descriptor(obj):
13    """
14    Returns True if obj is a descriptor, False otherwise.
15    """
16    return (
17            hasattr(obj, '__get__') or
18            hasattr(obj, '__set__') or
19            hasattr(obj, '__delete__')
20            )
21
22def _is_dunder(name):
23    """
24    Returns True if a __dunder__ name, False otherwise.
25    """
26    return (
27            len(name) > 4 and
28            name[:2] == name[-2:] == '__' and
29            name[2] != '_' and
30            name[-3] != '_'
31            )
32
33def _is_sunder(name):
34    """
35    Returns True if a _sunder_ name, False otherwise.
36    """
37    return (
38            len(name) > 2 and
39            name[0] == name[-1] == '_' and
40            name[1:2] != '_' and
41            name[-2:-1] != '_'
42            )
43
44def _is_private(cls_name, name):
45    # do not use `re` as `re` imports `enum`
46    pattern = '_%s__' % (cls_name, )
47    pat_len = len(pattern)
48    if (
49            len(name) > pat_len
50            and name.startswith(pattern)
51            and name[pat_len:pat_len+1] != ['_']
52            and (name[-1] != '_' or name[-2] != '_')
53        ):
54        return True
55    else:
56        return False
57
58def _make_class_unpicklable(cls):
59    """
60    Make the given class un-picklable.
61    """
62    def _break_on_call_reduce(self, proto):
63        raise TypeError('%r cannot be pickled' % self)
64    cls.__reduce_ex__ = _break_on_call_reduce
65    cls.__module__ = '<unknown>'
66
67_auto_null = object()
68class auto:
69    """
70    Instances are replaced with an appropriate value in Enum class suites.
71    """
72    value = _auto_null
73
74
75class _EnumDict(dict):
76    """
77    Track enum member order and ensure member names are not reused.
78
79    EnumMeta will use the names found in self._member_names as the
80    enumeration member names.
81    """
82    def __init__(self):
83        super().__init__()
84        self._member_names = []
85        self._last_values = []
86        self._ignore = []
87        self._auto_called = False
88
89    def __setitem__(self, key, value):
90        """
91        Changes anything not dundered or not a descriptor.
92
93        If an enum member name is used twice, an error is raised; duplicate
94        values are not checked for.
95
96        Single underscore (sunder) names are reserved.
97        """
98        if _is_private(self._cls_name, key):
99            import warnings
100            warnings.warn(
101                    "private variables, such as %r, will be normal attributes in 3.11"
102                        % (key, ),
103                    DeprecationWarning,
104                    stacklevel=2,
105                    )
106        if _is_sunder(key):
107            if key not in (
108                    '_order_', '_create_pseudo_member_',
109                    '_generate_next_value_', '_missing_', '_ignore_',
110                    ):
111                raise ValueError('_names_ are reserved for future Enum use')
112            if key == '_generate_next_value_':
113                # check if members already defined as auto()
114                if self._auto_called:
115                    raise TypeError("_generate_next_value_ must be defined before members")
116                setattr(self, '_generate_next_value', value)
117            elif key == '_ignore_':
118                if isinstance(value, str):
119                    value = value.replace(',',' ').split()
120                else:
121                    value = list(value)
122                self._ignore = value
123                already = set(value) & set(self._member_names)
124                if already:
125                    raise ValueError(
126                            '_ignore_ cannot specify already set names: %r'
127                            % (already, )
128                            )
129        elif _is_dunder(key):
130            if key == '__order__':
131                key = '_order_'
132        elif key in self._member_names:
133            # descriptor overwriting an enum?
134            raise TypeError('Attempted to reuse key: %r' % key)
135        elif key in self._ignore:
136            pass
137        elif not _is_descriptor(value):
138            if key in self:
139                # enum overwriting a descriptor?
140                raise TypeError('%r already defined as: %r' % (key, self[key]))
141            if isinstance(value, auto):
142                if value.value == _auto_null:
143                    value.value = self._generate_next_value(
144                            key,
145                            1,
146                            len(self._member_names),
147                            self._last_values[:],
148                            )
149                    self._auto_called = True
150                value = value.value
151            self._member_names.append(key)
152            self._last_values.append(value)
153        super().__setitem__(key, value)
154
155
156# Dummy value for Enum as EnumMeta explicitly checks for it, but of course
157# until EnumMeta finishes running the first time the Enum class doesn't exist.
158# This is also why there are checks in EnumMeta like `if Enum is not None`
159Enum = None
160
161class EnumMeta(type):
162    """
163    Metaclass for Enum
164    """
165    @classmethod
166    def __prepare__(metacls, cls, bases, **kwds):
167        # check that previous enum members do not exist
168        metacls._check_for_existing_members(cls, bases)
169        # create the namespace dict
170        enum_dict = _EnumDict()
171        enum_dict._cls_name = cls
172        # inherit previous flags and _generate_next_value_ function
173        member_type, first_enum = metacls._get_mixins_(cls, bases)
174        if first_enum is not None:
175            enum_dict['_generate_next_value_'] = getattr(
176                    first_enum, '_generate_next_value_', None,
177                    )
178        return enum_dict
179
180    def __new__(metacls, cls, bases, classdict, **kwds):
181        # an Enum class is final once enumeration items have been defined; it
182        # cannot be mixed with other types (int, float, etc.) if it has an
183        # inherited __new__ unless a new __new__ is defined (or the resulting
184        # class will fail).
185        #
186        # remove any keys listed in _ignore_
187        classdict.setdefault('_ignore_', []).append('_ignore_')
188        ignore = classdict['_ignore_']
189        for key in ignore:
190            classdict.pop(key, None)
191        member_type, first_enum = metacls._get_mixins_(cls, bases)
192        __new__, save_new, use_args = metacls._find_new_(
193                classdict, member_type, first_enum,
194                )
195
196        # save enum items into separate mapping so they don't get baked into
197        # the new class
198        enum_members = {k: classdict[k] for k in classdict._member_names}
199        for name in classdict._member_names:
200            del classdict[name]
201
202        # adjust the sunders
203        _order_ = classdict.pop('_order_', None)
204
205        # check for illegal enum names (any others?)
206        invalid_names = set(enum_members) & {'mro', ''}
207        if invalid_names:
208            raise ValueError('Invalid enum member name: {0}'.format(
209                ','.join(invalid_names)))
210
211        # create a default docstring if one has not been provided
212        if '__doc__' not in classdict:
213            classdict['__doc__'] = 'An enumeration.'
214
215        enum_class = super().__new__(metacls, cls, bases, classdict, **kwds)
216        enum_class._member_names_ = []               # names in definition order
217        enum_class._member_map_ = {}                 # name->value map
218        enum_class._member_type_ = member_type
219
220        # save DynamicClassAttribute attributes from super classes so we know
221        # if we can take the shortcut of storing members in the class dict
222        dynamic_attributes = {
223                k for c in enum_class.mro()
224                for k, v in c.__dict__.items()
225                if isinstance(v, DynamicClassAttribute)
226                }
227
228        # Reverse value->name map for hashable values.
229        enum_class._value2member_map_ = {}
230
231        # If a custom type is mixed into the Enum, and it does not know how
232        # to pickle itself, pickle.dumps will succeed but pickle.loads will
233        # fail.  Rather than have the error show up later and possibly far
234        # from the source, sabotage the pickle protocol for this class so
235        # that pickle.dumps also fails.
236        #
237        # However, if the new class implements its own __reduce_ex__, do not
238        # sabotage -- it's on them to make sure it works correctly.  We use
239        # __reduce_ex__ instead of any of the others as it is preferred by
240        # pickle over __reduce__, and it handles all pickle protocols.
241        if '__reduce_ex__' not in classdict:
242            if member_type is not object:
243                methods = ('__getnewargs_ex__', '__getnewargs__',
244                        '__reduce_ex__', '__reduce__')
245                if not any(m in member_type.__dict__ for m in methods):
246                    if '__new__' in classdict:
247                        # too late, sabotage
248                        _make_class_unpicklable(enum_class)
249                    else:
250                        # final attempt to verify that pickling would work:
251                        # travel mro until __new__ is found, checking for
252                        # __reduce__ and friends along the way -- if any of them
253                        # are found before/when __new__ is found, pickling should
254                        # work
255                        sabotage = None
256                        for chain in bases:
257                            for base in chain.__mro__:
258                                if base is object:
259                                    continue
260                                elif any(m in base.__dict__ for m in methods):
261                                    # found one, we're good
262                                    sabotage = False
263                                    break
264                                elif '__new__' in base.__dict__:
265                                    # not good
266                                    sabotage = True
267                                    break
268                            if sabotage is not None:
269                                break
270                        if sabotage:
271                            _make_class_unpicklable(enum_class)
272        # instantiate them, checking for duplicates as we go
273        # we instantiate first instead of checking for duplicates first in case
274        # a custom __new__ is doing something funky with the values -- such as
275        # auto-numbering ;)
276        for member_name in classdict._member_names:
277            value = enum_members[member_name]
278            if not isinstance(value, tuple):
279                args = (value, )
280            else:
281                args = value
282            if member_type is tuple:   # special case for tuple enums
283                args = (args, )     # wrap it one more time
284            if not use_args:
285                enum_member = __new__(enum_class)
286                if not hasattr(enum_member, '_value_'):
287                    enum_member._value_ = value
288            else:
289                enum_member = __new__(enum_class, *args)
290                if not hasattr(enum_member, '_value_'):
291                    if member_type is object:
292                        enum_member._value_ = value
293                    else:
294                        enum_member._value_ = member_type(*args)
295            value = enum_member._value_
296            enum_member._name_ = member_name
297            enum_member.__objclass__ = enum_class
298            enum_member.__init__(*args)
299            # If another member with the same value was already defined, the
300            # new member becomes an alias to the existing one.
301            for name, canonical_member in enum_class._member_map_.items():
302                if canonical_member._value_ == enum_member._value_:
303                    enum_member = canonical_member
304                    break
305            else:
306                # Aliases don't appear in member names (only in __members__).
307                enum_class._member_names_.append(member_name)
308            # performance boost for any member that would not shadow
309            # a DynamicClassAttribute
310            if member_name not in dynamic_attributes:
311                setattr(enum_class, member_name, enum_member)
312            # now add to _member_map_
313            enum_class._member_map_[member_name] = enum_member
314            try:
315                # This may fail if value is not hashable. We can't add the value
316                # to the map, and by-value lookups for this value will be
317                # linear.
318                enum_class._value2member_map_[value] = enum_member
319            except TypeError:
320                pass
321
322        # double check that repr and friends are not the mixin's or various
323        # things break (such as pickle)
324        # however, if the method is defined in the Enum itself, don't replace
325        # it
326        for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'):
327            if name in classdict:
328                continue
329            class_method = getattr(enum_class, name)
330            obj_method = getattr(member_type, name, None)
331            enum_method = getattr(first_enum, name, None)
332            if obj_method is not None and obj_method is class_method:
333                setattr(enum_class, name, enum_method)
334
335        # replace any other __new__ with our own (as long as Enum is not None,
336        # anyway) -- again, this is to support pickle
337        if Enum is not None:
338            # if the user defined their own __new__, save it before it gets
339            # clobbered in case they subclass later
340            if save_new:
341                enum_class.__new_member__ = __new__
342            enum_class.__new__ = Enum.__new__
343
344        # py3 support for definition order (helps keep py2/py3 code in sync)
345        if _order_ is not None:
346            if isinstance(_order_, str):
347                _order_ = _order_.replace(',', ' ').split()
348            if _order_ != enum_class._member_names_:
349                raise TypeError('member order does not match _order_')
350
351        return enum_class
352
353    def __bool__(self):
354        """
355        classes/types should always be True.
356        """
357        return True
358
359    def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1):
360        """
361        Either returns an existing member, or creates a new enum class.
362
363        This method is used both when an enum class is given a value to match
364        to an enumeration member (i.e. Color(3)) and for the functional API
365        (i.e. Color = Enum('Color', names='RED GREEN BLUE')).
366
367        When used for the functional API:
368
369        `value` will be the name of the new class.
370
371        `names` should be either a string of white-space/comma delimited names
372        (values will start at `start`), or an iterator/mapping of name, value pairs.
373
374        `module` should be set to the module this class is being created in;
375        if it is not set, an attempt to find that module will be made, but if
376        it fails the class will not be picklable.
377
378        `qualname` should be set to the actual location this class can be found
379        at in its module; by default it is set to the global scope.  If this is
380        not correct, unpickling will fail in some circumstances.
381
382        `type`, if set, will be mixed in as the first base class.
383        """
384        if names is None:  # simple value lookup
385            return cls.__new__(cls, value)
386        # otherwise, functional API: we're creating a new Enum type
387        return cls._create_(
388                value,
389                names,
390                module=module,
391                qualname=qualname,
392                type=type,
393                start=start,
394                )
395
396    def __contains__(cls, obj):
397        if not isinstance(obj, Enum):
398            import warnings
399            warnings.warn(
400                    "in 3.12 __contains__ will no longer raise TypeError, but will return True if\n"
401                    "obj is a member or a member's value",
402                    DeprecationWarning,
403                    stacklevel=2,
404                    )
405            raise TypeError(
406                "unsupported operand type(s) for 'in': '%s' and '%s'" % (
407                    type(obj).__qualname__, cls.__class__.__qualname__))
408        return isinstance(obj, cls) and obj._name_ in cls._member_map_
409
410    def __delattr__(cls, attr):
411        # nicer error message when someone tries to delete an attribute
412        # (see issue19025).
413        if attr in cls._member_map_:
414            raise AttributeError("%s: cannot delete Enum member." % cls.__name__)
415        super().__delattr__(attr)
416
417    def __dir__(self):
418        return (
419                ['__class__', '__doc__', '__members__', '__module__']
420                + self._member_names_
421                )
422
423    def __getattr__(cls, name):
424        """
425        Return the enum member matching `name`
426
427        We use __getattr__ instead of descriptors or inserting into the enum
428        class' __dict__ in order to support `name` and `value` being both
429        properties for enum members (which live in the class' __dict__) and
430        enum members themselves.
431        """
432        if _is_dunder(name):
433            raise AttributeError(name)
434        try:
435            return cls._member_map_[name]
436        except KeyError:
437            raise AttributeError(name) from None
438
439    def __getitem__(cls, name):
440        return cls._member_map_[name]
441
442    def __iter__(cls):
443        """
444        Returns members in definition order.
445        """
446        return (cls._member_map_[name] for name in cls._member_names_)
447
448    def __len__(cls):
449        return len(cls._member_names_)
450
451    @property
452    def __members__(cls):
453        """
454        Returns a mapping of member name->value.
455
456        This mapping lists all enum members, including aliases. Note that this
457        is a read-only view of the internal mapping.
458        """
459        return MappingProxyType(cls._member_map_)
460
461    def __repr__(cls):
462        return "<enum %r>" % cls.__name__
463
464    def __reversed__(cls):
465        """
466        Returns members in reverse definition order.
467        """
468        return (cls._member_map_[name] for name in reversed(cls._member_names_))
469
470    def __setattr__(cls, name, value):
471        """
472        Block attempts to reassign Enum members.
473
474        A simple assignment to the class namespace only changes one of the
475        several possible ways to get an Enum member from the Enum class,
476        resulting in an inconsistent Enumeration.
477        """
478        member_map = cls.__dict__.get('_member_map_', {})
479        if name in member_map:
480            raise AttributeError('Cannot reassign members.')
481        super().__setattr__(name, value)
482
483    def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, start=1):
484        """
485        Convenience method to create a new Enum class.
486
487        `names` can be:
488
489        * A string containing member names, separated either with spaces or
490          commas.  Values are incremented by 1 from `start`.
491        * An iterable of member names.  Values are incremented by 1 from `start`.
492        * An iterable of (member name, value) pairs.
493        * A mapping of member name -> value pairs.
494        """
495        metacls = cls.__class__
496        bases = (cls, ) if type is None else (type, cls)
497        _, first_enum = cls._get_mixins_(cls, bases)
498        classdict = metacls.__prepare__(class_name, bases)
499
500        # special processing needed for names?
501        if isinstance(names, str):
502            names = names.replace(',', ' ').split()
503        if isinstance(names, (tuple, list)) and names and isinstance(names[0], str):
504            original_names, names = names, []
505            last_values = []
506            for count, name in enumerate(original_names):
507                value = first_enum._generate_next_value_(name, start, count, last_values[:])
508                last_values.append(value)
509                names.append((name, value))
510
511        # Here, names is either an iterable of (name, value) or a mapping.
512        for item in names:
513            if isinstance(item, str):
514                member_name, member_value = item, names[item]
515            else:
516                member_name, member_value = item
517            classdict[member_name] = member_value
518        enum_class = metacls.__new__(metacls, class_name, bases, classdict)
519
520        # TODO: replace the frame hack if a blessed way to know the calling
521        # module is ever developed
522        if module is None:
523            try:
524                module = sys._getframe(2).f_globals['__name__']
525            except (AttributeError, ValueError, KeyError):
526                pass
527        if module is None:
528            _make_class_unpicklable(enum_class)
529        else:
530            enum_class.__module__ = module
531        if qualname is not None:
532            enum_class.__qualname__ = qualname
533
534        return enum_class
535
536    def _convert_(cls, name, module, filter, source=None):
537        """
538        Create a new Enum subclass that replaces a collection of global constants
539        """
540        # convert all constants from source (or module) that pass filter() to
541        # a new Enum called name, and export the enum and its members back to
542        # module;
543        # also, replace the __reduce_ex__ method so unpickling works in
544        # previous Python versions
545        module_globals = vars(sys.modules[module])
546        if source:
547            source = vars(source)
548        else:
549            source = module_globals
550        # _value2member_map_ is populated in the same order every time
551        # for a consistent reverse mapping of number to name when there
552        # are multiple names for the same number.
553        members = [
554                (name, value)
555                for name, value in source.items()
556                if filter(name)]
557        try:
558            # sort by value
559            members.sort(key=lambda t: (t[1], t[0]))
560        except TypeError:
561            # unless some values aren't comparable, in which case sort by name
562            members.sort(key=lambda t: t[0])
563        cls = cls(name, members, module=module)
564        cls.__reduce_ex__ = _reduce_ex_by_name
565        module_globals.update(cls.__members__)
566        module_globals[name] = cls
567        return cls
568
569    @staticmethod
570    def _check_for_existing_members(class_name, bases):
571        for chain in bases:
572            for base in chain.__mro__:
573                if issubclass(base, Enum) and base._member_names_:
574                    raise TypeError(
575                            "%s: cannot extend enumeration %r"
576                            % (class_name, base.__name__)
577                            )
578
579    @staticmethod
580    def _get_mixins_(class_name, bases):
581        """
582        Returns the type for creating enum members, and the first inherited
583        enum class.
584
585        bases: the tuple of bases that was given to __new__
586        """
587        if not bases:
588            return object, Enum
589
590        def _find_data_type(bases):
591            data_types = set()
592            for chain in bases:
593                candidate = None
594                for base in chain.__mro__:
595                    if base is object:
596                        continue
597                    elif issubclass(base, Enum):
598                        if base._member_type_ is not object:
599                            data_types.add(base._member_type_)
600                            break
601                    elif '__new__' in base.__dict__:
602                        if issubclass(base, Enum):
603                            continue
604                        data_types.add(candidate or base)
605                        break
606                    else:
607                        candidate = candidate or base
608            if len(data_types) > 1:
609                raise TypeError('%r: too many data types: %r' % (class_name, data_types))
610            elif data_types:
611                return data_types.pop()
612            else:
613                return None
614
615        # ensure final parent class is an Enum derivative, find any concrete
616        # data type, and check that Enum has no members
617        first_enum = bases[-1]
618        if not issubclass(first_enum, Enum):
619            raise TypeError("new enumerations should be created as "
620                    "`EnumName([mixin_type, ...] [data_type,] enum_type)`")
621        member_type = _find_data_type(bases) or object
622        if first_enum._member_names_:
623            raise TypeError("Cannot extend enumerations")
624        return member_type, first_enum
625
626    @staticmethod
627    def _find_new_(classdict, member_type, first_enum):
628        """
629        Returns the __new__ to be used for creating the enum members.
630
631        classdict: the class dictionary given to __new__
632        member_type: the data type whose __new__ will be used by default
633        first_enum: enumeration to check for an overriding __new__
634        """
635        # now find the correct __new__, checking to see of one was defined
636        # by the user; also check earlier enum classes in case a __new__ was
637        # saved as __new_member__
638        __new__ = classdict.get('__new__', None)
639
640        # should __new__ be saved as __new_member__ later?
641        save_new = __new__ is not None
642
643        if __new__ is None:
644            # check all possibles for __new_member__ before falling back to
645            # __new__
646            for method in ('__new_member__', '__new__'):
647                for possible in (member_type, first_enum):
648                    target = getattr(possible, method, None)
649                    if target not in {
650                            None,
651                            None.__new__,
652                            object.__new__,
653                            Enum.__new__,
654                            }:
655                        __new__ = target
656                        break
657                if __new__ is not None:
658                    break
659            else:
660                __new__ = object.__new__
661
662        # if a non-object.__new__ is used then whatever value/tuple was
663        # assigned to the enum member name will be passed to __new__ and to the
664        # new enum member's __init__
665        if __new__ is object.__new__:
666            use_args = False
667        else:
668            use_args = True
669        return __new__, save_new, use_args
670
671
672class Enum(metaclass=EnumMeta):
673    """
674    Generic enumeration.
675
676    Derive from this class to define new enumerations.
677    """
678    def __new__(cls, value):
679        # all enum instances are actually created during class construction
680        # without calling this method; this method is called by the metaclass'
681        # __call__ (i.e. Color(3) ), and by pickle
682        if type(value) is cls:
683            # For lookups like Color(Color.RED)
684            return value
685        # by-value search for a matching enum member
686        # see if it's in the reverse mapping (for hashable values)
687        try:
688            return cls._value2member_map_[value]
689        except KeyError:
690            # Not found, no need to do long O(n) search
691            pass
692        except TypeError:
693            # not there, now do long search -- O(n) behavior
694            for member in cls._member_map_.values():
695                if member._value_ == value:
696                    return member
697        # still not found -- try _missing_ hook
698        try:
699            exc = None
700            result = cls._missing_(value)
701        except Exception as e:
702            exc = e
703            result = None
704        try:
705            if isinstance(result, cls):
706                return result
707            else:
708                ve_exc = ValueError("%r is not a valid %s" % (value, cls.__qualname__))
709                if result is None and exc is None:
710                    raise ve_exc
711                elif exc is None:
712                    exc = TypeError(
713                            'error in %s._missing_: returned %r instead of None or a valid member'
714                            % (cls.__name__, result)
715                            )
716                if not isinstance(exc, ValueError):
717                    exc.__context__ = ve_exc
718                raise exc
719        finally:
720            # ensure all variables that could hold an exception are destroyed
721            exc = None
722            ve_exc = None
723
724    def _generate_next_value_(name, start, count, last_values):
725        """
726        Generate the next value when not given.
727
728        name: the name of the member
729        start: the initial start value or None
730        count: the number of existing members
731        last_value: the last value assigned or None
732        """
733        for last_value in reversed(last_values):
734            try:
735                return last_value + 1
736            except TypeError:
737                pass
738        else:
739            return start
740
741    @classmethod
742    def _missing_(cls, value):
743        return None
744
745    def __repr__(self):
746        return "<%s.%s: %r>" % (
747                self.__class__.__name__, self._name_, self._value_)
748
749    def __str__(self):
750        return "%s.%s" % (self.__class__.__name__, self._name_)
751
752    def __dir__(self):
753        """
754        Returns all members and all public methods
755        """
756        added_behavior = [
757                m
758                for cls in self.__class__.mro()
759                for m in cls.__dict__
760                if m[0] != '_' and m not in self._member_map_
761                ] + [m for m in self.__dict__ if m[0] != '_']
762        return (['__class__', '__doc__', '__module__'] + added_behavior)
763
764    def __format__(self, format_spec):
765        """
766        Returns format using actual value type unless __str__ has been overridden.
767        """
768        # mixed-in Enums should use the mixed-in type's __format__, otherwise
769        # we can get strange results with the Enum name showing up instead of
770        # the value
771
772        # pure Enum branch, or branch with __str__ explicitly overridden
773        str_overridden = type(self).__str__ not in (Enum.__str__, Flag.__str__)
774        if self._member_type_ is object or str_overridden:
775            cls = str
776            val = str(self)
777        # mix-in branch
778        else:
779            cls = self._member_type_
780            val = self._value_
781        return cls.__format__(val, format_spec)
782
783    def __hash__(self):
784        return hash(self._name_)
785
786    def __reduce_ex__(self, proto):
787        return self.__class__, (self._value_, )
788
789    # DynamicClassAttribute is used to provide access to the `name` and
790    # `value` properties of enum members while keeping some measure of
791    # protection from modification, while still allowing for an enumeration
792    # to have members named `name` and `value`.  This works because enumeration
793    # members are not set directly on the enum class -- __getattr__ is
794    # used to look them up.
795
796    @DynamicClassAttribute
797    def name(self):
798        """The name of the Enum member."""
799        return self._name_
800
801    @DynamicClassAttribute
802    def value(self):
803        """The value of the Enum member."""
804        return self._value_
805
806
807class IntEnum(int, Enum):
808    """Enum where members are also (and must be) ints"""
809
810
811def _reduce_ex_by_name(self, proto):
812    return self.name
813
814class Flag(Enum):
815    """
816    Support for flags
817    """
818
819    def _generate_next_value_(name, start, count, last_values):
820        """
821        Generate the next value when not given.
822
823        name: the name of the member
824        start: the initial start value or None
825        count: the number of existing members
826        last_value: the last value assigned or None
827        """
828        if not count:
829            return start if start is not None else 1
830        for last_value in reversed(last_values):
831            try:
832                high_bit = _high_bit(last_value)
833                break
834            except Exception:
835                raise TypeError('Invalid Flag value: %r' % last_value) from None
836        return 2 ** (high_bit+1)
837
838    @classmethod
839    def _missing_(cls, value):
840        """
841        Returns member (possibly creating it) if one can be found for value.
842        """
843        original_value = value
844        if value < 0:
845            value = ~value
846        possible_member = cls._create_pseudo_member_(value)
847        if original_value < 0:
848            possible_member = ~possible_member
849        return possible_member
850
851    @classmethod
852    def _create_pseudo_member_(cls, value):
853        """
854        Create a composite member iff value contains only members.
855        """
856        pseudo_member = cls._value2member_map_.get(value, None)
857        if pseudo_member is None:
858            # verify all bits are accounted for
859            _, extra_flags = _decompose(cls, value)
860            if extra_flags:
861                raise ValueError("%r is not a valid %s" % (value, cls.__qualname__))
862            # construct a singleton enum pseudo-member
863            pseudo_member = object.__new__(cls)
864            pseudo_member._name_ = None
865            pseudo_member._value_ = value
866            # use setdefault in case another thread already created a composite
867            # with this value
868            pseudo_member = cls._value2member_map_.setdefault(value, pseudo_member)
869        return pseudo_member
870
871    def __contains__(self, other):
872        """
873        Returns True if self has at least the same flags set as other.
874        """
875        if not isinstance(other, self.__class__):
876            raise TypeError(
877                "unsupported operand type(s) for 'in': '%s' and '%s'" % (
878                    type(other).__qualname__, self.__class__.__qualname__))
879        return other._value_ & self._value_ == other._value_
880
881    def __repr__(self):
882        cls = self.__class__
883        if self._name_ is not None:
884            return '<%s.%s: %r>' % (cls.__name__, self._name_, self._value_)
885        members, uncovered = _decompose(cls, self._value_)
886        return '<%s.%s: %r>' % (
887                cls.__name__,
888                '|'.join([str(m._name_ or m._value_) for m in members]),
889                self._value_,
890                )
891
892    def __str__(self):
893        cls = self.__class__
894        if self._name_ is not None:
895            return '%s.%s' % (cls.__name__, self._name_)
896        members, uncovered = _decompose(cls, self._value_)
897        if len(members) == 1 and members[0]._name_ is None:
898            return '%s.%r' % (cls.__name__, members[0]._value_)
899        else:
900            return '%s.%s' % (
901                    cls.__name__,
902                    '|'.join([str(m._name_ or m._value_) for m in members]),
903                    )
904
905    def __bool__(self):
906        return bool(self._value_)
907
908    def __or__(self, other):
909        if not isinstance(other, self.__class__):
910            return NotImplemented
911        return self.__class__(self._value_ | other._value_)
912
913    def __and__(self, other):
914        if not isinstance(other, self.__class__):
915            return NotImplemented
916        return self.__class__(self._value_ & other._value_)
917
918    def __xor__(self, other):
919        if not isinstance(other, self.__class__):
920            return NotImplemented
921        return self.__class__(self._value_ ^ other._value_)
922
923    def __invert__(self):
924        members, uncovered = _decompose(self.__class__, self._value_)
925        inverted = self.__class__(0)
926        for m in self.__class__:
927            if m not in members and not (m._value_ & self._value_):
928                inverted = inverted | m
929        return self.__class__(inverted)
930
931
932class IntFlag(int, Flag):
933    """
934    Support for integer-based Flags
935    """
936
937    @classmethod
938    def _missing_(cls, value):
939        """
940        Returns member (possibly creating it) if one can be found for value.
941        """
942        if not isinstance(value, int):
943            raise ValueError("%r is not a valid %s" % (value, cls.__qualname__))
944        new_member = cls._create_pseudo_member_(value)
945        return new_member
946
947    @classmethod
948    def _create_pseudo_member_(cls, value):
949        """
950        Create a composite member iff value contains only members.
951        """
952        pseudo_member = cls._value2member_map_.get(value, None)
953        if pseudo_member is None:
954            need_to_create = [value]
955            # get unaccounted for bits
956            _, extra_flags = _decompose(cls, value)
957            # timer = 10
958            while extra_flags:
959                # timer -= 1
960                bit = _high_bit(extra_flags)
961                flag_value = 2 ** bit
962                if (flag_value not in cls._value2member_map_ and
963                        flag_value not in need_to_create
964                        ):
965                    need_to_create.append(flag_value)
966                if extra_flags == -flag_value:
967                    extra_flags = 0
968                else:
969                    extra_flags ^= flag_value
970            for value in reversed(need_to_create):
971                # construct singleton pseudo-members
972                pseudo_member = int.__new__(cls, value)
973                pseudo_member._name_ = None
974                pseudo_member._value_ = value
975                # use setdefault in case another thread already created a composite
976                # with this value
977                pseudo_member = cls._value2member_map_.setdefault(value, pseudo_member)
978        return pseudo_member
979
980    def __or__(self, other):
981        if not isinstance(other, (self.__class__, int)):
982            return NotImplemented
983        result = self.__class__(self._value_ | self.__class__(other)._value_)
984        return result
985
986    def __and__(self, other):
987        if not isinstance(other, (self.__class__, int)):
988            return NotImplemented
989        return self.__class__(self._value_ & self.__class__(other)._value_)
990
991    def __xor__(self, other):
992        if not isinstance(other, (self.__class__, int)):
993            return NotImplemented
994        return self.__class__(self._value_ ^ self.__class__(other)._value_)
995
996    __ror__ = __or__
997    __rand__ = __and__
998    __rxor__ = __xor__
999
1000    def __invert__(self):
1001        result = self.__class__(~self._value_)
1002        return result
1003
1004
1005def _high_bit(value):
1006    """
1007    returns index of highest bit, or -1 if value is zero or negative
1008    """
1009    return value.bit_length() - 1
1010
1011def unique(enumeration):
1012    """
1013    Class decorator for enumerations ensuring unique member values.
1014    """
1015    duplicates = []
1016    for name, member in enumeration.__members__.items():
1017        if name != member.name:
1018            duplicates.append((name, member.name))
1019    if duplicates:
1020        alias_details = ', '.join(
1021                ["%s -> %s" % (alias, name) for (alias, name) in duplicates])
1022        raise ValueError('duplicate values found in %r: %s' %
1023                (enumeration, alias_details))
1024    return enumeration
1025
1026def _decompose(flag, value):
1027    """
1028    Extract all members from the value.
1029    """
1030    # _decompose is only called if the value is not named
1031    not_covered = value
1032    negative = value < 0
1033    members = []
1034    for member in flag:
1035        member_value = member.value
1036        if member_value and member_value & value == member_value:
1037            members.append(member)
1038            not_covered &= ~member_value
1039    if not negative:
1040        tmp = not_covered
1041        while tmp:
1042            flag_value = 2 ** _high_bit(tmp)
1043            if flag_value in flag._value2member_map_:
1044                members.append(flag._value2member_map_[flag_value])
1045                not_covered &= ~flag_value
1046            tmp &= ~flag_value
1047    if not members and value in flag._value2member_map_:
1048        members.append(flag._value2member_map_[value])
1049    members.sort(key=lambda m: m._value_, reverse=True)
1050    if len(members) > 1 and members[0].value == value:
1051        # we have the breakdown, don't need the value member itself
1052        members.pop(0)
1053    return members, not_covered
1054