1 module(enum
) ## needed in guile atm
4 from types
import MappingProxyType
, DynamicClassAttribute
5 from functools
import reduce
6 from operator
import or_
as _or_
8 # try _collections first to reduce startup cost
10 from _collections
import OrderedDict
12 from collections
import OrderedDict
17 'Enum', 'IntEnum', 'Flag', 'IntFlag',
22 def _is_descriptor(obj
):
23 """Returns True if obj is a descriptor, False otherwise."""
25 hasattr(obj
, '__get__') or
26 hasattr(obj
, '__set__') or
27 hasattr(obj
, '__delete__'))
31 """Returns True if a __dunder__ name, False otherwise."""
32 return (name
[:2] == name
[-2:] == '__' and
34 name
[-3:-2] != '_' and
39 """Returns True if a _sunder_ name, False otherwise."""
40 return (name
[0] == name
[-1] == '_' and
42 name
[-2:-1] != '_' and
45 def _make_class_unpicklable(cls
):
46 """Make the given class un-picklable."""
47 def _break_on_call_reduce(self
, proto
):
48 raise TypeError('%r cannot be pickled' % self
)
49 cls
.__reduce
_ex
__ = _break_on_call_reduce
50 cls
.__module
__ = '<unknown>'
55 Instances are replaced with an appropriate value in Enum class suites.
60 class _EnumDict(dict):
61 """Track enum member order and ensure member names are not reused.
63 EnumMeta will use the names found in self._member_names as the
64 enumeration member names.
69 self
._member
_names
= []
70 self
._last
_values
= []
72 def __setitem__(self
, key
, value
):
73 """Changes anything not dundered or not a descriptor.
75 If an enum member name is used twice, an error is raised; duplicate
76 values are not checked for.
78 Single underscore (sunder) names are reserved.
83 '_order_', '_create_pseudo_member_',
84 '_generate_next_value_', '_missing_',
86 raise ValueError('_names_ are reserved for future Enum use')
87 if key
== '_generate_next_value_':
88 setattr(self
, '_generate_next_value', value
)
90 if key
== '__order__':
92 elif key
in self
._member
_names
:
93 # descriptor overwriting an enum?
94 raise TypeError('Attempted to reuse key: %r' % key
)
95 elif not _is_descriptor(value
):
97 # enum overwriting a descriptor?
98 raise TypeError('%r already defined as: %r' % (key
, self
[key
]))
99 if isinstance(value
, auto
):
100 if value
.value
== _auto_null
:
101 value
.value
= self
._generate
_next
_value
(key
, 1, len(self
._member
_names
), self
._last
_values
[:])
103 self
._member
_names
.append(key
)
104 self
._last
_values
.append(value
)
105 super().__setitem
__(key
, value
)
108 # Dummy value for Enum as EnumMeta explicitly checks for it, but of course
109 # until EnumMeta finishes running the first time the Enum class doesn't exist.
110 # This is also why there are checks in EnumMeta like `if Enum is not None`
114 class EnumMeta(type):
115 """Metaclass for Enum"""
117 def __prepare__(metacls
, cls
, bases
):
118 # create the namespace dict
119 enum_dict
= _EnumDict()
120 # inherit previous flags and _generate_next_value_ function
121 member_type
, first_enum
= metacls
._get
_mixins
_(bases
)
122 if first_enum
is not None:
123 enum_dict
['_generate_next_value_'] = getattr(first_enum
, '_generate_next_value_', None)
126 def __new__(metacls
, cls
, bases
, classdict
):
127 # an Enum class is final once enumeration items have been defined; it
128 # cannot be mixed with other types (int, float, etc.) if it has an
129 # inherited __new__ unless a new __new__ is defined (or the resulting
131 member_type
, first_enum
= metacls
._get
_mixins
_(bases
)
132 __new__
, save_new
, use_args
= metacls
._find
_new
_(classdict
, member_type
,
135 # save enum items into separate mapping so they don't get baked into
137 enum_members
= {k
: classdict
[k
] for k
in classdict
._member
_names
}
138 for name
in classdict
._member
_names
:
142 _order_
= classdict
.pop('_order_', None)
144 # check for illegal enum names (any others?)
145 invalid_names
= set(enum_members
) & {'mro', }
147 raise ValueError('Invalid enum member name: {0}'.format(
148 ','.join(invalid_names
)))
150 # create a default docstring if one has not been provided
151 if '__doc__' not in classdict
:
152 classdict
['__doc__'] = 'An enumeration.'
154 # create our new Enum type
155 enum_class
= super().__new
__(metacls
, cls
, bases
, classdict
)
156 enum_class
._member
_names
_ = [] # names in definition order
157 enum_class
._member
_map
_ = OrderedDict() # name->value map
158 enum_class
._member
_type
_ = member_type
160 # save attributes from super classes so we know if we can take
161 # the shortcut of storing members in the class dict
162 base_attributes
= {a
for b
in enum_class
.mro() for a
in b
.__dict
__}
164 # Reverse value->name map for hashable values.
165 enum_class
._value
2member
_map
_ = {}
167 # If a custom type is mixed into the Enum, and it does not know how
168 # to pickle itself, pickle.dumps will succeed but pickle.loads will
169 # fail. Rather than have the error show up later and possibly far
170 # from the source, sabotage the pickle protocol for this class so
171 # that pickle.dumps also fails.
173 # However, if the new class implements its own __reduce_ex__, do not
174 # sabotage -- it's on them to make sure it works correctly. We use
175 # __reduce_ex__ instead of any of the others as it is preferred by
176 # pickle over __reduce__, and it handles all pickle protocols.
177 if '__reduce_ex__' not in classdict
:
178 if member_type
is not object:
179 methods
= ('__getnewargs_ex__', '__getnewargs__',
180 '__reduce_ex__', '__reduce__')
181 if not any(m
in member_type
.__dict
__ for m
in methods
):
182 _make_class_unpicklable(enum_class
)
184 # instantiate them, checking for duplicates as we go
185 # we instantiate first instead of checking for duplicates first in case
186 # a custom __new__ is doing something funky with the values -- such as
188 for member_name
in classdict
._member
_names
:
189 value
= enum_members
[member_name
]
190 if not isinstance(value
, tuple):
194 if member_type
is tuple: # special case for tuple enums
195 args
= (args
, ) # wrap it one more time
197 enum_member
= __new__(enum_class
)
198 if not hasattr(enum_member
, '_value_'):
199 enum_member
._value
_ = value
201 enum_member
= __new__(enum_class
, *args
)
202 if not hasattr(enum_member
, '_value_'):
203 if member_type
is object:
204 enum_member
._value
_ = value
206 enum_member
._value
_ = member_type(*args
)
207 value
= enum_member
._value
_
208 enum_member
._name
_ = member_name
209 enum_member
.__objclass
__ = enum_class
210 enum_member
.__init
__(*args
)
211 # If another member with the same value was already defined, the
212 # new member becomes an alias to the existing one.
213 for name
, canonical_member
in enum_class
._member
_map
_.items():
214 if canonical_member
._value
_ == enum_member
._value
_:
215 enum_member
= canonical_member
218 # Aliases don't appear in member names (only in __members__).
219 enum_class
._member
_names
_.append(member_name
)
220 # performance boost for any member that would not shadow
221 # a DynamicClassAttribute
222 if member_name
not in base_attributes
:
223 setattr(enum_class
, member_name
, enum_member
)
224 # now add to _member_map_
225 enum_class
._member
_map
_[member_name
] = enum_member
227 # This may fail if value is not hashable. We can't add the value
228 # to the map, and by-value lookups for this value will be
230 enum_class
._value
2member
_map
_[value
] = enum_member
234 # double check that repr and friends are not the mixin's or various
235 # things break (such as pickle)
236 for name
in ('__repr__', '__str__', '__format__', '__reduce_ex__'):
237 class_method
= getattr(enum_class
, name
)
238 obj_method
= getattr(member_type
, name
, None)
239 enum_method
= getattr(first_enum
, name
, None)
240 if obj_method
is not None and obj_method
is class_method
:
241 setattr(enum_class
, name
, enum_method
)
243 # replace any other __new__ with our own (as long as Enum is not None,
244 # anyway) -- again, this is to support pickle
246 # if the user defined their own __new__, save it before it gets
247 # clobbered in case they subclass later
249 enum_class
.__new
_member
__ = __new__
250 enum_class
.__new
__ = Enum
.__new
__
252 # py3 support for definition order (helps keep py2/py3 code in sync)
253 if _order_
is not None:
254 if isinstance(_order_
, str):
255 _order_
= _order_
.replace(',', ' ').split()
256 if _order_
!= enum_class
._member
_names
_:
257 raise TypeError('member order does not match _order_')
263 classes/types should always be True.
267 def __call__(cls
, value
, names
=None, *, module
=None, qualname
=None, type=None, start
=1):
268 """Either returns an existing member, or creates a new enum class.
270 This method is used both when an enum class is given a value to match
271 to an enumeration member (i.e. Color(3)) and for the functional API
272 (i.e. Color = Enum('Color', names='RED GREEN BLUE')).
274 When used for the functional API:
276 `value` will be the name of the new class.
278 `names` should be either a string of white-space/comma delimited names
279 (values will start at `start`), or an iterator/mapping of name, value pairs.
281 `module` should be set to the module this class is being created in;
282 if it is not set, an attempt to find that module will be made, but if
283 it fails the class will not be picklable.
285 `qualname` should be set to the actual location this class can be found
286 at in its module; by default it is set to the global scope. If this is
287 not correct, unpickling will fail in some circumstances.
289 `type`, if set, will be mixed in as the first base class.
292 if names
is None: # simple value lookup
293 return cls
.__new
__(cls
, value
)
294 # otherwise, functional API: we're creating a new Enum type
295 return cls
._create
_(value
, names
, module
=module
, qualname
=qualname
, type=type, start
=start
)
297 def __contains__(cls
, member
):
298 return isinstance(member
, cls
) and member
._name
_ in cls
._member
_map
_
300 def __delattr__(cls
, attr
):
301 # nicer error message when someone tries to delete an attribute
303 if attr
in cls
._member
_map
_:
304 raise AttributeError(
305 "%s: cannot delete Enum member." % cls
.__name
__)
306 super().__delattr
__(attr
)
309 return (['__class__', '__doc__', '__members__', '__module__'] +
312 def __getattr__(cls
, name
):
313 """Return the enum member matching `name`
315 We use __getattr__ instead of descriptors or inserting into the enum
316 class' __dict__ in order to support `name` and `value` being both
317 properties for enum members (which live in the class' __dict__) and
318 enum members themselves.
322 raise AttributeError(name
)
324 return cls
._member
_map
_[name
]
326 raise AttributeError(name
) from None
328 def __getitem__(cls
, name
):
329 return cls
._member
_map
_[name
]
332 return (cls
._member
_map
_[name
] for name
in cls
._member
_names
_)
335 return len(cls
._member
_names
_)
338 def __members__(cls
):
339 """Returns a mapping of member name->value.
341 This mapping lists all enum members, including aliases. Note that this
342 is a read-only view of the internal mapping.
345 return MappingProxyType(cls
._member
_map
_)
348 return "<enum %r>" % cls
.__name
__
350 def __reversed__(cls
):
351 return (cls
._member
_map
_[name
] for name
in reversed(cls
._member
_names
_))
353 def __setattr__(cls
, name
, value
):
354 """Block attempts to reassign Enum members.
356 A simple assignment to the class namespace only changes one of the
357 several possible ways to get an Enum member from the Enum class,
358 resulting in an inconsistent Enumeration.
361 member_map
= cls
.__dict
__.get('_member_map_', {})
362 if name
in member_map
:
363 raise AttributeError('Cannot reassign members.')
364 super().__setattr
__(name
, value
)
366 def _create_(cls
, class_name
, names
=None, *, module
=None, qualname
=None, type=None, start
=1):
367 """Convenience method to create a new Enum class.
371 * A string containing member names, separated either with spaces or
372 commas. Values are incremented by 1 from `start`.
373 * An iterable of member names. Values are incremented by 1 from `start`.
374 * An iterable of (member name, value) pairs.
375 * A mapping of member name -> value pairs.
378 metacls
= cls
.__class
__
379 bases
= (cls
, ) if type is None else (type, cls
)
380 _
, first_enum
= cls
._get
_mixins
_(bases
)
381 classdict
= metacls
.__prepare
__(class_name
, bases
)
383 # special processing needed for names?
384 if isinstance(names
, str):
385 names
= names
.replace(',', ' ').split()
386 if isinstance(names
, (tuple, list)) and names
and isinstance(names
[0], str):
387 original_names
, names
= names
, []
389 for count
, name
in enumerate(original_names
):
390 value
= first_enum
._generate
_next
_value
_(name
, start
, count
, last_values
[:])
391 last_values
.append(value
)
392 names
.append((name
, value
))
394 # Here, names is either an iterable of (name, value) or a mapping.
396 if isinstance(item
, str):
397 member_name
, member_value
= item
, names
[item
]
399 member_name
, member_value
= item
400 classdict
[member_name
] = member_value
401 enum_class
= metacls
.__new
__(metacls
, class_name
, bases
, classdict
)
403 # TODO: replace the frame hack if a blessed way to know the calling
404 # module is ever developed
407 module
= sys
._getframe
(2).f_globals
['__name__']
408 except (AttributeError, ValueError) as exc
:
411 _make_class_unpicklable(enum_class
)
413 enum_class
.__module
__ = module
414 if qualname
is not None:
415 enum_class
.__qualname
__ = qualname
420 def _get_mixins_(bases
):
421 """Returns the type for creating enum members, and the first inherited
424 bases: the tuple of bases that was given to __new__
430 # double check that we are not subclassing a class with existing
431 # enumeration members; while we're at it, see if any other data
432 # type has been mixed in so we can use the correct __new__
433 member_type
= first_enum
= None
435 if (base
is not Enum
and
436 issubclass(base
, Enum
) and
437 base
._member
_names
_):
438 raise TypeError("Cannot extend enumerations")
439 # base is now the last base in bases
440 if not issubclass(base
, Enum
):
441 raise TypeError("new enumerations must be created as "
442 "`ClassName([mixin_type,] enum_type)`")
444 # get correct mix-in type (either mix-in type of Enum subclass, or
445 # first base if last base is Enum)
446 if not issubclass(bases
[0], Enum
):
447 member_type
= bases
[0] # first data type
448 first_enum
= bases
[-1] # enum type
450 for base
in bases
[0].__mro
__:
451 # most common: (IntEnum, int, Enum, object)
452 # possible: (<Enum 'AutoIntEnum'>, <Enum 'IntEnum'>,
453 # <class 'int'>, <Enum 'Enum'>,
455 if issubclass(base
, Enum
):
456 if first_enum
is None:
459 if member_type
is None:
462 return member_type
, first_enum
465 def _find_new_(classdict
, member_type
, first_enum
):
466 """Returns the __new__ to be used for creating the enum members.
468 classdict: the class dictionary given to __new__
469 member_type: the data type whose __new__ will be used by default
470 first_enum: enumeration to check for an overriding __new__
473 # now find the correct __new__, checking to see of one was defined
474 # by the user; also check earlier enum classes in case a __new__ was
475 # saved as __new_member__
476 __new__
= classdict
.get('__new__', None)
478 # should __new__ be saved as __new_member__ later?
479 save_new
= __new__
is not None
482 # check all possibles for __new_member__ before falling back to
484 for method
in ('__new_member__', '__new__'):
485 for possible
in (member_type
, first_enum
):
486 target
= getattr(possible
, method
, None)
495 if __new__
is not None:
498 __new__
= object.__new
__
500 # if a non-object.__new__ is used then whatever value/tuple was
501 # assigned to the enum member name will be passed to __new__ and to the
502 # new enum member's __init__
503 if __new__
is object.__new
__:
508 return __new__
, save_new
, use_args
510 class Enum(metaclass
=EnumMeta
):
511 """Generic enumeration.
513 Derive from this class to define new enumerations.
516 def __new__(cls
, value
):
517 # all enum instances are actually created during class construction
518 # without calling this method; this method is called by the metaclass'
519 # __call__ (i.e. Color(3) ), and by pickle
520 if type(value
) is cls
:
521 # For lookups like Color(Color.RED)
523 # by-value search for a matching enum member
524 # see if it's in the reverse mapping (for hashable values)
526 if value
in cls
._value
2member
_map
_:
527 return cls
._value
2member
_map
_[value
]
529 # not there, now do long search -- O(n) behavior
530 for member
in cls
._member
_map
_.values():
531 if member
._value
_ == value
:
533 # still not found -- try _missing_ hook
534 return cls
._missing
_(value
)
536 def _generate_next_value_(name
, start
, count
, last_values
):
537 for last_value
in reversed(last_values
):
539 return last_value
+ 1
546 def _missing_(cls
, value
):
547 raise ValueError("%r is not a valid %s" % (value
, cls
.__name
__))
550 return "<%s.%s: %r>" % (
551 self
.__class
__.__name
__, self
._name
_, self
._value
_)
554 return "%s.%s" % (self
.__class
__.__name
__, self
._name
_)
559 for cls
in self
.__class
__.mro()
560 for m
in cls
.__dict
__
561 if m
[0] != '_' and m
not in self
._member
_map
_
563 return (['__class__', '__doc__', '__module__'] + added_behavior
)
565 def __format__(self
, format_spec
):
566 # mixed-in Enums should use the mixed-in type's __format__, otherwise
567 # we can get strange results with the Enum name showing up instead of
571 if self
._member
_type
_ is object:
576 cls
= self
._member
_type
_
578 return cls
.__format
__(val
, format_spec
)
581 return hash(self
._name
_)
583 def __reduce_ex__(self
, proto
):
584 return self
.__class
__, (self
._value
_, )
586 # DynamicClassAttribute is used to provide access to the `name` and
587 # `value` properties of enum members while keeping some measure of
588 # protection from modification, while still allowing for an enumeration
589 # to have members named `name` and `value`. This works because enumeration
590 # members are not set directly on the enum class -- __getattr__ is
591 # used to look them up.
593 @DynamicClassAttribute
595 """The name of the Enum member."""
598 @DynamicClassAttribute
600 """The value of the Enum member."""
604 def _convert(cls
, name
, module
, filter, source
=None):
606 Create a new Enum subclass that replaces a collection of global constants
608 # convert all constants from source (or module) that pass filter() to
609 # a new Enum called name, and export the enum and its members back to
611 # also, replace the __reduce_ex__ method so unpickling works in
612 # previous Python versions
613 module_globals
= vars(sys
.modules
[module
])
615 source
= vars(source
)
617 source
= module_globals
618 # We use an OrderedDict of sorted source keys so that the
619 # _value2member_map is populated in the same order every time
620 # for a consistent reverse mapping of number to name when there
621 # are multiple names for the same number rather than varying
622 # between runs due to hash randomization of the module dictionary.
625 for name
in source
.keys()
629 members
.sort(key
=lambda t
: (t
[1], t
[0]))
631 # unless some values aren't comparable, in which case sort by name
632 members
.sort(key
=lambda t
: t
[0])
633 cls
= cls(name
, members
, module
=module
)
634 cls
.__reduce
_ex
__ = _reduce_ex_by_name
635 module_globals
.update(cls
.__members
__)
636 module_globals
[name
] = cls
640 class IntEnum(int, Enum
):
641 """Enum where members are also (and must be) ints"""
644 def _reduce_ex_by_name(self
, proto
):
648 """Support for flags"""
650 def _generate_next_value_(name
, start
, count
, last_values
):
652 Generate the next value when not given.
654 name: the name of the member
655 start: the initital start value or None
656 count: the number of existing members
657 last_value: the last value assigned or None
660 return start
if start
is not None else 1
661 for last_value
in reversed(last_values
):
663 high_bit
= _high_bit(last_value
)
666 raise TypeError('Invalid Flag value: %r' % last_value
) from None
667 return 2 ** (high_bit
+1)
670 def _missing_(cls
, value
):
671 original_value
= value
674 possible_member
= cls
._create
_pseudo
_member
_(value
)
675 if original_value
< 0:
676 possible_member
= ~possible_member
677 return possible_member
680 def _create_pseudo_member_(cls
, value
):
682 Create a composite member iff value contains only members.
684 pseudo_member
= cls
._value
2member
_map
_.get(value
, None)
685 if pseudo_member
is None:
686 # verify all bits are accounted for
687 _
, extra_flags
= _decompose(cls
, value
)
689 raise ValueError("%r is not a valid %s" % (value
, cls
.__name
__))
690 # construct a singleton enum pseudo-member
691 pseudo_member
= object.__new
__(cls
)
692 pseudo_member
._name
_ = None
693 pseudo_member
._value
_ = value
694 # use setdefault in case another thread already created a composite
696 pseudo_member
= cls
._value
2member
_map
_.setdefault(value
, pseudo_member
)
699 def __contains__(self
, other
):
700 if not isinstance(other
, self
.__class
__):
701 return NotImplemented
702 return other
._value
_ & self
._value
_ == other
._value
_
706 if self
._name
_ is not None:
707 return '<%s.%s: %r>' % (cls
.__name
__, self
._name
_, self
._value
_)
708 members
, uncovered
= _decompose(cls
, self
._value
_)
709 return '<%s.%s: %r>' % (
711 '|'.join([str(m
._name
_ or m
._value
_) for m
in members
]),
717 if self
._name
_ is not None:
718 return '%s.%s' % (cls
.__name
__, self
._name
_)
719 members
, uncovered
= _decompose(cls
, self
._value
_)
720 if len(members
) == 1 and members
[0]._name
_ is None:
721 return '%s.%r' % (cls
.__name
__, members
[0]._value
_)
725 '|'.join([str(m
._name
_ or m
._value
_) for m
in members
]),
729 return bool(self
._value
_)
731 def __or__(self
, other
):
732 if not isinstance(other
, self
.__class
__):
733 return NotImplemented
734 return self
.__class
__(self
._value
_ | other
._value
_)
736 def __and__(self
, other
):
737 if not isinstance(other
, self
.__class
__):
738 return NotImplemented
739 return self
.__class
__(self
._value
_ & other
._value
_)
741 def __xor__(self
, other
):
742 if not isinstance(other
, self
.__class
__):
743 return NotImplemented
744 return self
.__class
__(self
._value
_ ^ other
._value
_)
746 def __invert__(self
):
747 members
, uncovered
= _decompose(self
.__class
__, self
._value
_)
749 m
for m
in self
.__class
__
750 if m
not in members
and not m
._value
_ & self
._value
_
752 inverted
= reduce(_or_
, inverted_members
, self
.__class
__(0))
753 return self
.__class
__(inverted
)
756 class IntFlag(int, Flag
):
757 """Support for integer-based Flags"""
760 def _missing_(cls
, value
):
761 if not isinstance(value
, int):
762 raise ValueError("%r is not a valid %s" % (value
, cls
.__name
__))
763 new_member
= cls
._create
_pseudo
_member
_(value
)
767 def _create_pseudo_member_(cls
, value
):
768 pseudo_member
= cls
._value
2member
_map
_.get(value
, None)
769 if pseudo_member
is None:
770 need_to_create
= [value
]
771 # get unaccounted for bits
772 _
, extra_flags
= _decompose(cls
, value
)
776 bit
= _high_bit(extra_flags
)
777 flag_value
= 2 ** bit
778 if (flag_value
not in cls
._value
2member
_map
_ and
779 flag_value
not in need_to_create
781 need_to_create
.append(flag_value
)
782 if extra_flags
== -flag_value
:
785 extra_flags ^
= flag_value
786 for value
in reversed(need_to_create
):
787 # construct singleton pseudo-members
788 pseudo_member
= int.__new
__(cls
, value
)
789 pseudo_member
._name
_ = None
790 pseudo_member
._value
_ = value
791 # use setdefault in case another thread already created a composite
793 pseudo_member
= cls
._value
2member
_map
_.setdefault(value
, pseudo_member
)
796 def __or__(self
, other
):
797 if not isinstance(other
, (self
.__class
__, int)):
798 return NotImplemented
799 result
= self
.__class
__(self
._value
_ | self
.__class
__(other
)._value
_)
802 def __and__(self
, other
):
803 if not isinstance(other
, (self
.__class
__, int)):
804 return NotImplemented
805 return self
.__class
__(self
._value
_ & self
.__class
__(other
)._value
_)
807 def __xor__(self
, other
):
808 if not isinstance(other
, (self
.__class
__, int)):
809 return NotImplemented
810 return self
.__class
__(self
._value
_ ^ self
.__class
__(other
)._value
_)
816 def __invert__(self
):
817 result
= self
.__class
__(~self
._value
_)
821 def _high_bit(value
):
822 """returns index of highest bit, or -1 if value is zero or negative"""
823 return value
.bit_length() - 1
825 def unique(enumeration
):
826 """Class decorator for enumerations ensuring unique member values."""
828 for name
, member
in enumeration
.__members
__.items():
829 if name
!= member
.name
:
830 duplicates
.append((name
, member
.name
))
832 alias_details
= ', '.join(
833 ["%s -> %s" % (alias
, name
) for (alias
, name
) in duplicates
])
834 raise ValueError('duplicate values found in %r: %s' %
835 (enumeration
, alias_details
))
838 def _decompose(flag
, value
):
839 """Extract all members from the value."""
840 # _decompose is only called if the value is not named
843 # issue29167: wrap accesses to _value2member_map_ in a list to avoid race
844 # conditions between iterating over it and having more psuedo-
845 # members added to it
847 # only check for named flags
850 for v
, m
in list(flag
._value
2member
_map
_.items())
851 if m
.name
is not None
854 # check for named flags and powers-of-two flags
857 for v
, m
in list(flag
._value
2member
_map
_.items())
858 if m
.name
is not None or _power_of_two(v
)
861 for member
, member_value
in flags_to_check
:
862 if member_value
and member_value
& value
== member_value
:
863 members
.append(member
)
864 not_covered
&= ~member_value
865 if not members
and value
in flag
._value
2member
_map
_:
866 members
.append(flag
._value
2member
_map
_[value
])
867 members
.sort(key
=lambda m
: m
._value
_, reverse
=True)
868 if len(members
) > 1 and members
[0].value
== value
:
869 # we have the breakdown, don't need the value member itself
871 return members
, not_covered
873 def _power_of_two(value
):
876 return value
== 2 ** _high_bit(value
)