blob: 3c459ea4113d0b5b84c67515e1d7b074f962a5d0 [file] [log] [blame]
Ethan Furman6b3d64a2013-06-14 16:55:46 -07001import sys
Ethan Furmane03ea372013-09-25 07:14:41 -07002from types import MappingProxyType, DynamicClassAttribute
Ethan Furman6b3d64a2013-06-14 16:55:46 -07003
Ethan Furmane5754ab2015-09-17 22:03:52 -07004
Ethan Furmanc16595e2016-09-10 23:36:59 -07005__all__ = [
6 'EnumMeta',
7 'Enum', 'IntEnum', 'Flag', 'IntFlag',
8 'auto', 'unique',
9 ]
Ethan Furman6b3d64a2013-06-14 16:55:46 -070010
11
Ethan Furman101e0742013-09-15 12:34:36 -070012def _is_descriptor(obj):
13 """Returns True if obj is a descriptor, False otherwise."""
14 return (
15 hasattr(obj, '__get__') or
16 hasattr(obj, '__set__') or
17 hasattr(obj, '__delete__'))
18
19
Ethan Furman6b3d64a2013-06-14 16:55:46 -070020def _is_dunder(name):
21 """Returns True if a __dunder__ name, False otherwise."""
Brennan D Baraban8b914d22019-03-03 14:09:11 -080022 return (len(name) > 4 and
23 name[:2] == name[-2:] == '__' and
24 name[2] != '_' and
25 name[-3] != '_')
Ethan Furman6b3d64a2013-06-14 16:55:46 -070026
27
28def _is_sunder(name):
29 """Returns True if a _sunder_ name, False otherwise."""
Brennan D Baraban8b914d22019-03-03 14:09:11 -080030 return (len(name) > 2 and
31 name[0] == name[-1] == '_' and
Ethan Furman6b3d64a2013-06-14 16:55:46 -070032 name[1:2] != '_' and
Brennan D Baraban8b914d22019-03-03 14:09:11 -080033 name[-2:-1] != '_')
34
Ethan Furman6b3d64a2013-06-14 16:55:46 -070035
Ethan Furman6b3d64a2013-06-14 16:55:46 -070036def _make_class_unpicklable(cls):
37 """Make the given class un-picklable."""
Ethan Furmanca1b7942014-02-08 11:36:27 -080038 def _break_on_call_reduce(self, proto):
Ethan Furman6b3d64a2013-06-14 16:55:46 -070039 raise TypeError('%r cannot be pickled' % self)
Ethan Furmanca1b7942014-02-08 11:36:27 -080040 cls.__reduce_ex__ = _break_on_call_reduce
Ethan Furman6b3d64a2013-06-14 16:55:46 -070041 cls.__module__ = '<unknown>'
42
Ethan Furman3515dcc2016-09-18 13:15:41 -070043_auto_null = object()
Ethan Furmanc16595e2016-09-10 23:36:59 -070044class auto:
45 """
46 Instances are replaced with an appropriate value in Enum class suites.
47 """
Ethan Furman3515dcc2016-09-18 13:15:41 -070048 value = _auto_null
Ethan Furmanc16595e2016-09-10 23:36:59 -070049
Ethan Furman101e0742013-09-15 12:34:36 -070050
Ethan Furman6b3d64a2013-06-14 16:55:46 -070051class _EnumDict(dict):
Ethan Furman101e0742013-09-15 12:34:36 -070052 """Track enum member order and ensure member names are not reused.
Ethan Furman6b3d64a2013-06-14 16:55:46 -070053
54 EnumMeta will use the names found in self._member_names as the
55 enumeration member names.
56
57 """
58 def __init__(self):
59 super().__init__()
60 self._member_names = []
Ethan Furmanc16595e2016-09-10 23:36:59 -070061 self._last_values = []
Ethan Furmana4b1bb42018-01-22 07:56:37 -080062 self._ignore = []
Ethan Onstottd9a43e22020-04-28 13:20:55 -040063 self._auto_called = False
Ethan Furman6b3d64a2013-06-14 16:55:46 -070064
65 def __setitem__(self, key, value):
Ethan Furman101e0742013-09-15 12:34:36 -070066 """Changes anything not dundered or not a descriptor.
Ethan Furman6b3d64a2013-06-14 16:55:46 -070067
68 If an enum member name is used twice, an error is raised; duplicate
69 values are not checked for.
70
71 Single underscore (sunder) names are reserved.
72
73 """
74 if _is_sunder(key):
Ethan Furmanee47e5c2016-08-31 00:12:15 -070075 if key not in (
Ethan Furman3515dcc2016-09-18 13:15:41 -070076 '_order_', '_create_pseudo_member_',
Ethan Furmana4b1bb42018-01-22 07:56:37 -080077 '_generate_next_value_', '_missing_', '_ignore_',
Ethan Furmanee47e5c2016-08-31 00:12:15 -070078 ):
Zackery Spytz2ec67522020-09-13 14:27:51 -060079 raise ValueError(f'_sunder_ names, such as "{key}", are '
80 'reserved for future Enum use')
Ethan Furmanc16595e2016-09-10 23:36:59 -070081 if key == '_generate_next_value_':
Ethan Onstottd9a43e22020-04-28 13:20:55 -040082 # check if members already defined as auto()
83 if self._auto_called:
84 raise TypeError("_generate_next_value_ must be defined before members")
Ethan Furmanc16595e2016-09-10 23:36:59 -070085 setattr(self, '_generate_next_value', value)
Ethan Furmana4b1bb42018-01-22 07:56:37 -080086 elif key == '_ignore_':
87 if isinstance(value, str):
88 value = value.replace(',',' ').split()
89 else:
90 value = list(value)
91 self._ignore = value
92 already = set(value) & set(self._member_names)
93 if already:
94 raise ValueError('_ignore_ cannot specify already set names: %r' % (already, ))
Ethan Furman101e0742013-09-15 12:34:36 -070095 elif _is_dunder(key):
Ethan Furmane8e61272016-08-20 07:19:31 -070096 if key == '__order__':
97 key = '_order_'
Ethan Furman101e0742013-09-15 12:34:36 -070098 elif key in self._member_names:
99 # descriptor overwriting an enum?
100 raise TypeError('Attempted to reuse key: %r' % key)
Ethan Furmana4b1bb42018-01-22 07:56:37 -0800101 elif key in self._ignore:
102 pass
Ethan Furman101e0742013-09-15 12:34:36 -0700103 elif not _is_descriptor(value):
104 if key in self:
105 # enum overwriting a descriptor?
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700106 raise TypeError('%r already defined as: %r' % (key, self[key]))
Ethan Furmanc16595e2016-09-10 23:36:59 -0700107 if isinstance(value, auto):
Ethan Furman3515dcc2016-09-18 13:15:41 -0700108 if value.value == _auto_null:
109 value.value = self._generate_next_value(key, 1, len(self._member_names), self._last_values[:])
Ethan Furmanfc23a942020-09-16 12:37:54 -0700110 self._auto_called = True
Ethan Furman3515dcc2016-09-18 13:15:41 -0700111 value = value.value
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700112 self._member_names.append(key)
Ethan Furmanc16595e2016-09-10 23:36:59 -0700113 self._last_values.append(value)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700114 super().__setitem__(key, value)
115
116
Ezio Melotti9a3777e2013-08-17 15:53:55 +0300117# Dummy value for Enum as EnumMeta explicitly checks for it, but of course
118# until EnumMeta finishes running the first time the Enum class doesn't exist.
119# This is also why there are checks in EnumMeta like `if Enum is not None`
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700120Enum = None
121
Ethan Furman332dbc72016-08-20 00:00:52 -0700122
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700123class EnumMeta(type):
124 """Metaclass for Enum"""
125 @classmethod
Ethan Furman332dbc72016-08-20 00:00:52 -0700126 def __prepare__(metacls, cls, bases):
Ethan Furman3064dbf2020-09-16 07:11:57 -0700127 # check that previous enum members do not exist
128 metacls._check_for_existing_members(cls, bases)
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700129 # create the namespace dict
130 enum_dict = _EnumDict()
131 # inherit previous flags and _generate_next_value_ function
Ethan Furman3064dbf2020-09-16 07:11:57 -0700132 member_type, first_enum = metacls._get_mixins_(cls, bases)
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700133 if first_enum is not None:
134 enum_dict['_generate_next_value_'] = getattr(first_enum, '_generate_next_value_', None)
135 return enum_dict
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700136
Ethan Furman65a5a472016-09-01 23:55:19 -0700137 def __new__(metacls, cls, bases, classdict):
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700138 # an Enum class is final once enumeration items have been defined; it
139 # cannot be mixed with other types (int, float, etc.) if it has an
140 # inherited __new__ unless a new __new__ is defined (or the resulting
141 # class will fail).
Ethan Furmana4b1bb42018-01-22 07:56:37 -0800142 #
143 # remove any keys listed in _ignore_
144 classdict.setdefault('_ignore_', []).append('_ignore_')
145 ignore = classdict['_ignore_']
146 for key in ignore:
147 classdict.pop(key, None)
Ethan Furman3064dbf2020-09-16 07:11:57 -0700148 member_type, first_enum = metacls._get_mixins_(cls, bases)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700149 __new__, save_new, use_args = metacls._find_new_(classdict, member_type,
150 first_enum)
151
152 # save enum items into separate mapping so they don't get baked into
153 # the new class
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700154 enum_members = {k: classdict[k] for k in classdict._member_names}
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700155 for name in classdict._member_names:
156 del classdict[name]
157
Ethan Furmane8e61272016-08-20 07:19:31 -0700158 # adjust the sunders
159 _order_ = classdict.pop('_order_', None)
160
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700161 # check for illegal enum names (any others?)
Brennan D Baraban8b914d22019-03-03 14:09:11 -0800162 invalid_names = set(enum_members) & {'mro', ''}
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700163 if invalid_names:
164 raise ValueError('Invalid enum member name: {0}'.format(
165 ','.join(invalid_names)))
166
Ethan Furman48a724f2015-04-11 23:23:06 -0700167 # create a default docstring if one has not been provided
168 if '__doc__' not in classdict:
169 classdict['__doc__'] = 'An enumeration.'
170
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700171 # create our new Enum type
172 enum_class = super().__new__(metacls, cls, bases, classdict)
Ethan Furman520ad572013-07-19 19:47:21 -0700173 enum_class._member_names_ = [] # names in definition order
INADA Naokie57f91a2018-06-19 01:14:26 +0900174 enum_class._member_map_ = {} # name->value map
Ethan Furman5e5a8232013-08-04 08:42:23 -0700175 enum_class._member_type_ = member_type
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700176
orlnub1230fb9fad2018-09-12 20:28:53 +0300177 # save DynamicClassAttribute attributes from super classes so we know
178 # if we can take the shortcut of storing members in the class dict
179 dynamic_attributes = {k for c in enum_class.mro()
180 for k, v in c.__dict__.items()
181 if isinstance(v, DynamicClassAttribute)}
Ethan Furman354ecf12015-03-11 08:43:12 -0700182
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700183 # Reverse value->name map for hashable values.
Ethan Furman520ad572013-07-19 19:47:21 -0700184 enum_class._value2member_map_ = {}
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700185
Ethan Furman2da95042014-03-03 12:42:52 -0800186 # If a custom type is mixed into the Enum, and it does not know how
187 # to pickle itself, pickle.dumps will succeed but pickle.loads will
188 # fail. Rather than have the error show up later and possibly far
189 # from the source, sabotage the pickle protocol for this class so
190 # that pickle.dumps also fails.
191 #
192 # However, if the new class implements its own __reduce_ex__, do not
193 # sabotage -- it's on them to make sure it works correctly. We use
194 # __reduce_ex__ instead of any of the others as it is preferred by
195 # pickle over __reduce__, and it handles all pickle protocols.
196 if '__reduce_ex__' not in classdict:
Ethan Furmandc870522014-02-18 12:37:12 -0800197 if member_type is not object:
198 methods = ('__getnewargs_ex__', '__getnewargs__',
199 '__reduce_ex__', '__reduce__')
Ethan Furman2da95042014-03-03 12:42:52 -0800200 if not any(m in member_type.__dict__ for m in methods):
Ethan Furmandc870522014-02-18 12:37:12 -0800201 _make_class_unpicklable(enum_class)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700202
203 # instantiate them, checking for duplicates as we go
204 # we instantiate first instead of checking for duplicates first in case
205 # a custom __new__ is doing something funky with the values -- such as
206 # auto-numbering ;)
207 for member_name in classdict._member_names:
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700208 value = enum_members[member_name]
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700209 if not isinstance(value, tuple):
210 args = (value, )
211 else:
212 args = value
213 if member_type is tuple: # special case for tuple enums
214 args = (args, ) # wrap it one more time
215 if not use_args:
216 enum_member = __new__(enum_class)
Ethan Furmanb41803e2013-07-25 13:50:45 -0700217 if not hasattr(enum_member, '_value_'):
218 enum_member._value_ = value
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700219 else:
220 enum_member = __new__(enum_class, *args)
Ethan Furmanb41803e2013-07-25 13:50:45 -0700221 if not hasattr(enum_member, '_value_'):
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700222 if member_type is object:
223 enum_member._value_ = value
224 else:
225 enum_member._value_ = member_type(*args)
Ethan Furman520ad572013-07-19 19:47:21 -0700226 value = enum_member._value_
Ethan Furman520ad572013-07-19 19:47:21 -0700227 enum_member._name_ = member_name
Ethan Furmanc850f342013-09-15 16:59:35 -0700228 enum_member.__objclass__ = enum_class
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700229 enum_member.__init__(*args)
230 # If another member with the same value was already defined, the
231 # new member becomes an alias to the existing one.
Ethan Furman520ad572013-07-19 19:47:21 -0700232 for name, canonical_member in enum_class._member_map_.items():
Ethan Furman0081f232014-09-16 17:31:23 -0700233 if canonical_member._value_ == enum_member._value_:
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700234 enum_member = canonical_member
235 break
236 else:
237 # Aliases don't appear in member names (only in __members__).
Ethan Furman520ad572013-07-19 19:47:21 -0700238 enum_class._member_names_.append(member_name)
Ethan Furman354ecf12015-03-11 08:43:12 -0700239 # performance boost for any member that would not shadow
240 # a DynamicClassAttribute
orlnub1230fb9fad2018-09-12 20:28:53 +0300241 if member_name not in dynamic_attributes:
Ethan Furman354ecf12015-03-11 08:43:12 -0700242 setattr(enum_class, member_name, enum_member)
243 # now add to _member_map_
Ethan Furman520ad572013-07-19 19:47:21 -0700244 enum_class._member_map_[member_name] = enum_member
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700245 try:
246 # This may fail if value is not hashable. We can't add the value
247 # to the map, and by-value lookups for this value will be
248 # linear.
Ethan Furman520ad572013-07-19 19:47:21 -0700249 enum_class._value2member_map_[value] = enum_member
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700250 except TypeError:
251 pass
252
253 # double check that repr and friends are not the mixin's or various
254 # things break (such as pickle)
Ethan Furman22415ad2020-09-15 16:28:25 -0700255 # however, if the method is defined in the Enum itself, don't replace
256 # it
Ethan Furmandc870522014-02-18 12:37:12 -0800257 for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'):
Ethan Furman22415ad2020-09-15 16:28:25 -0700258 if name in classdict:
259 continue
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700260 class_method = getattr(enum_class, name)
261 obj_method = getattr(member_type, name, None)
262 enum_method = getattr(first_enum, name, None)
263 if obj_method is not None and obj_method is class_method:
264 setattr(enum_class, name, enum_method)
265
266 # replace any other __new__ with our own (as long as Enum is not None,
267 # anyway) -- again, this is to support pickle
268 if Enum is not None:
269 # if the user defined their own __new__, save it before it gets
270 # clobbered in case they subclass later
271 if save_new:
272 enum_class.__new_member__ = __new__
273 enum_class.__new__ = Enum.__new__
Ethan Furmane8e61272016-08-20 07:19:31 -0700274
275 # py3 support for definition order (helps keep py2/py3 code in sync)
276 if _order_ is not None:
277 if isinstance(_order_, str):
278 _order_ = _order_.replace(',', ' ').split()
279 if _order_ != enum_class._member_names_:
280 raise TypeError('member order does not match _order_')
281
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700282 return enum_class
283
Ethan Furman5de67b12016-04-13 23:52:09 -0700284 def __bool__(self):
285 """
286 classes/types should always be True.
287 """
288 return True
289
Ethan Furmand9925a12014-09-16 20:35:55 -0700290 def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1):
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700291 """Either returns an existing member, or creates a new enum class.
292
293 This method is used both when an enum class is given a value to match
294 to an enumeration member (i.e. Color(3)) and for the functional API
Ethan Furman23bb6f42016-11-21 09:22:05 -0800295 (i.e. Color = Enum('Color', names='RED GREEN BLUE')).
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700296
Ethan Furman2da95042014-03-03 12:42:52 -0800297 When used for the functional API:
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700298
Ethan Furman2da95042014-03-03 12:42:52 -0800299 `value` will be the name of the new class.
300
301 `names` should be either a string of white-space/comma delimited names
Ethan Furmand9925a12014-09-16 20:35:55 -0700302 (values will start at `start`), or an iterator/mapping of name, value pairs.
Ethan Furman2da95042014-03-03 12:42:52 -0800303
304 `module` should be set to the module this class is being created in;
305 if it is not set, an attempt to find that module will be made, but if
306 it fails the class will not be picklable.
307
308 `qualname` should be set to the actual location this class can be found
309 at in its module; by default it is set to the global scope. If this is
310 not correct, unpickling will fail in some circumstances.
311
312 `type`, if set, will be mixed in as the first base class.
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700313
314 """
315 if names is None: # simple value lookup
316 return cls.__new__(cls, value)
317 # otherwise, functional API: we're creating a new Enum type
Ethan Furmand9925a12014-09-16 20:35:55 -0700318 return cls._create_(value, names, module=module, qualname=qualname, type=type, start=start)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700319
320 def __contains__(cls, member):
Rahul Jha94306522018-09-10 23:51:04 +0530321 if not isinstance(member, Enum):
322 raise TypeError(
323 "unsupported operand type(s) for 'in': '%s' and '%s'" % (
324 type(member).__qualname__, cls.__class__.__qualname__))
Ethan Furman0081f232014-09-16 17:31:23 -0700325 return isinstance(member, cls) and member._name_ in cls._member_map_
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700326
Ethan Furman64a99722013-09-22 16:18:19 -0700327 def __delattr__(cls, attr):
328 # nicer error message when someone tries to delete an attribute
329 # (see issue19025).
330 if attr in cls._member_map_:
331 raise AttributeError(
332 "%s: cannot delete Enum member." % cls.__name__)
333 super().__delattr__(attr)
334
Ethan Furman388a3922013-08-12 06:51:41 -0700335 def __dir__(self):
Ethan Furman64a99722013-09-22 16:18:19 -0700336 return (['__class__', '__doc__', '__members__', '__module__'] +
337 self._member_names_)
Ethan Furman388a3922013-08-12 06:51:41 -0700338
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700339 def __getattr__(cls, name):
340 """Return the enum member matching `name`
341
342 We use __getattr__ instead of descriptors or inserting into the enum
343 class' __dict__ in order to support `name` and `value` being both
344 properties for enum members (which live in the class' __dict__) and
345 enum members themselves.
346
347 """
348 if _is_dunder(name):
349 raise AttributeError(name)
350 try:
Ethan Furman520ad572013-07-19 19:47:21 -0700351 return cls._member_map_[name]
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700352 except KeyError:
353 raise AttributeError(name) from None
354
355 def __getitem__(cls, name):
Ethan Furman520ad572013-07-19 19:47:21 -0700356 return cls._member_map_[name]
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700357
358 def __iter__(cls):
Ethan Furman520ad572013-07-19 19:47:21 -0700359 return (cls._member_map_[name] for name in cls._member_names_)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700360
361 def __len__(cls):
Ethan Furman520ad572013-07-19 19:47:21 -0700362 return len(cls._member_names_)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700363
Ethan Furman2131a4a2013-09-14 18:11:24 -0700364 @property
365 def __members__(cls):
366 """Returns a mapping of member name->value.
367
368 This mapping lists all enum members, including aliases. Note that this
369 is a read-only view of the internal mapping.
370
371 """
372 return MappingProxyType(cls._member_map_)
373
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700374 def __repr__(cls):
375 return "<enum %r>" % cls.__name__
376
Ethan Furman2131a4a2013-09-14 18:11:24 -0700377 def __reversed__(cls):
378 return (cls._member_map_[name] for name in reversed(cls._member_names_))
379
Ethan Furmanf203f2d2013-09-06 07:16:48 -0700380 def __setattr__(cls, name, value):
381 """Block attempts to reassign Enum members.
382
383 A simple assignment to the class namespace only changes one of the
384 several possible ways to get an Enum member from the Enum class,
385 resulting in an inconsistent Enumeration.
386
387 """
388 member_map = cls.__dict__.get('_member_map_', {})
389 if name in member_map:
390 raise AttributeError('Cannot reassign members.')
391 super().__setattr__(name, value)
392
anentropicb8e21f12018-04-16 04:40:35 +0100393 def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, start=1):
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700394 """Convenience method to create a new Enum class.
395
396 `names` can be:
397
398 * A string containing member names, separated either with spaces or
Ethan Furmand9925a12014-09-16 20:35:55 -0700399 commas. Values are incremented by 1 from `start`.
400 * An iterable of member names. Values are incremented by 1 from `start`.
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700401 * An iterable of (member name, value) pairs.
Ethan Furmand9925a12014-09-16 20:35:55 -0700402 * A mapping of member name -> value pairs.
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700403
404 """
405 metacls = cls.__class__
406 bases = (cls, ) if type is None else (type, cls)
Ethan Furman3064dbf2020-09-16 07:11:57 -0700407 _, first_enum = cls._get_mixins_(cls, bases)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700408 classdict = metacls.__prepare__(class_name, bases)
409
410 # special processing needed for names?
411 if isinstance(names, str):
412 names = names.replace(',', ' ').split()
Dong-hee Nadcc8ce42017-06-22 01:52:32 +0900413 if isinstance(names, (tuple, list)) and names and isinstance(names[0], str):
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700414 original_names, names = names, []
Ethan Furmanc16595e2016-09-10 23:36:59 -0700415 last_values = []
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700416 for count, name in enumerate(original_names):
Ethan Furmanc16595e2016-09-10 23:36:59 -0700417 value = first_enum._generate_next_value_(name, start, count, last_values[:])
418 last_values.append(value)
419 names.append((name, value))
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700420
421 # Here, names is either an iterable of (name, value) or a mapping.
422 for item in names:
423 if isinstance(item, str):
424 member_name, member_value = item, names[item]
425 else:
426 member_name, member_value = item
427 classdict[member_name] = member_value
428 enum_class = metacls.__new__(metacls, class_name, bases, classdict)
429
430 # TODO: replace the frame hack if a blessed way to know the calling
431 # module is ever developed
432 if module is None:
433 try:
434 module = sys._getframe(2).f_globals['__name__']
Pablo Galindo293dd232019-11-19 21:34:03 +0000435 except (AttributeError, ValueError, KeyError):
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700436 pass
437 if module is None:
438 _make_class_unpicklable(enum_class)
439 else:
440 enum_class.__module__ = module
Ethan Furmanca1b7942014-02-08 11:36:27 -0800441 if qualname is not None:
442 enum_class.__qualname__ = qualname
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700443
444 return enum_class
445
orlnub1230fb9fad2018-09-12 20:28:53 +0300446 def _convert_(cls, name, module, filter, source=None):
447 """
448 Create a new Enum subclass that replaces a collection of global constants
449 """
450 # convert all constants from source (or module) that pass filter() to
451 # a new Enum called name, and export the enum and its members back to
452 # module;
453 # also, replace the __reduce_ex__ method so unpickling works in
454 # previous Python versions
455 module_globals = vars(sys.modules[module])
456 if source:
457 source = vars(source)
458 else:
459 source = module_globals
460 # _value2member_map_ is populated in the same order every time
461 # for a consistent reverse mapping of number to name when there
462 # are multiple names for the same number.
463 members = [
464 (name, value)
465 for name, value in source.items()
466 if filter(name)]
467 try:
468 # sort by value
469 members.sort(key=lambda t: (t[1], t[0]))
470 except TypeError:
471 # unless some values aren't comparable, in which case sort by name
472 members.sort(key=lambda t: t[0])
473 cls = cls(name, members, module=module)
474 cls.__reduce_ex__ = _reduce_ex_by_name
475 module_globals.update(cls.__members__)
476 module_globals[name] = cls
477 return cls
478
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700479 @staticmethod
Ethan Furman3064dbf2020-09-16 07:11:57 -0700480 def _check_for_existing_members(class_name, bases):
481 for chain in bases:
482 for base in chain.__mro__:
483 if issubclass(base, Enum) and base._member_names_:
484 raise TypeError("%s: cannot extend enumeration %r" % (class_name, base.__name__))
485
486 @staticmethod
487 def _get_mixins_(class_name, bases):
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700488 """Returns the type for creating enum members, and the first inherited
489 enum class.
490
491 bases: the tuple of bases that was given to __new__
492
493 """
494 if not bases:
495 return object, Enum
496
Ethan Furman5bdab642018-09-21 19:03:09 -0700497 def _find_data_type(bases):
Ethan Furmanbff01f32020-09-15 15:56:26 -0700498 data_types = []
Ethan Furman5bdab642018-09-21 19:03:09 -0700499 for chain in bases:
Ethan Furmanbff01f32020-09-15 15:56:26 -0700500 candidate = None
Ethan Furman5bdab642018-09-21 19:03:09 -0700501 for base in chain.__mro__:
502 if base is object:
503 continue
504 elif '__new__' in base.__dict__:
Ethan Furmancd453852018-10-05 23:29:36 -0700505 if issubclass(base, Enum):
Ethan Furman5bdab642018-09-21 19:03:09 -0700506 continue
Ethan Furmanbff01f32020-09-15 15:56:26 -0700507 data_types.append(candidate or base)
508 break
509 elif not issubclass(base, Enum):
510 candidate = base
511 if len(data_types) > 1:
Ethan Furman3064dbf2020-09-16 07:11:57 -0700512 raise TypeError('%r: too many data types: %r' % (class_name, data_types))
Ethan Furmanbff01f32020-09-15 15:56:26 -0700513 elif data_types:
514 return data_types[0]
515 else:
516 return None
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700517
Ethan Furman5bdab642018-09-21 19:03:09 -0700518 # ensure final parent class is an Enum derivative, find any concrete
519 # data type, and check that Enum has no members
520 first_enum = bases[-1]
521 if not issubclass(first_enum, Enum):
522 raise TypeError("new enumerations should be created as "
523 "`EnumName([mixin_type, ...] [data_type,] enum_type)`")
524 member_type = _find_data_type(bases) or object
525 if first_enum._member_names_:
526 raise TypeError("Cannot extend enumerations")
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700527 return member_type, first_enum
528
529 @staticmethod
530 def _find_new_(classdict, member_type, first_enum):
531 """Returns the __new__ to be used for creating the enum members.
532
533 classdict: the class dictionary given to __new__
534 member_type: the data type whose __new__ will be used by default
535 first_enum: enumeration to check for an overriding __new__
536
537 """
538 # now find the correct __new__, checking to see of one was defined
539 # by the user; also check earlier enum classes in case a __new__ was
540 # saved as __new_member__
541 __new__ = classdict.get('__new__', None)
542
543 # should __new__ be saved as __new_member__ later?
544 save_new = __new__ is not None
545
546 if __new__ is None:
547 # check all possibles for __new_member__ before falling back to
548 # __new__
549 for method in ('__new_member__', '__new__'):
550 for possible in (member_type, first_enum):
551 target = getattr(possible, method, None)
552 if target not in {
553 None,
554 None.__new__,
555 object.__new__,
556 Enum.__new__,
557 }:
558 __new__ = target
559 break
560 if __new__ is not None:
561 break
562 else:
563 __new__ = object.__new__
564
565 # if a non-object.__new__ is used then whatever value/tuple was
566 # assigned to the enum member name will be passed to __new__ and to the
567 # new enum member's __init__
568 if __new__ is object.__new__:
569 use_args = False
570 else:
571 use_args = True
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700572 return __new__, save_new, use_args
573
574
575class Enum(metaclass=EnumMeta):
576 """Generic enumeration.
577
578 Derive from this class to define new enumerations.
579
580 """
581 def __new__(cls, value):
582 # all enum instances are actually created during class construction
583 # without calling this method; this method is called by the metaclass'
584 # __call__ (i.e. Color(3) ), and by pickle
585 if type(value) is cls:
Ethan Furman23bb6f42016-11-21 09:22:05 -0800586 # For lookups like Color(Color.RED)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700587 return value
588 # by-value search for a matching enum member
589 # see if it's in the reverse mapping (for hashable values)
Ethan Furman2aa27322013-07-19 19:35:56 -0700590 try:
Andrew Svetlov34ae04f2018-12-26 20:45:33 +0200591 return cls._value2member_map_[value]
592 except KeyError:
593 # Not found, no need to do long O(n) search
594 pass
Ethan Furman2aa27322013-07-19 19:35:56 -0700595 except TypeError:
596 # not there, now do long search -- O(n) behavior
Ethan Furman520ad572013-07-19 19:47:21 -0700597 for member in cls._member_map_.values():
Ethan Furman0081f232014-09-16 17:31:23 -0700598 if member._value_ == value:
Ethan Furman2aa27322013-07-19 19:35:56 -0700599 return member
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700600 # still not found -- try _missing_ hook
Ethan Furman019f0a02018-09-12 11:43:34 -0700601 try:
602 exc = None
603 result = cls._missing_(value)
604 except Exception as e:
605 exc = e
606 result = None
607 if isinstance(result, cls):
608 return result
609 else:
Walter Dörwald323842c2019-07-18 20:37:13 +0200610 ve_exc = ValueError("%r is not a valid %s" % (value, cls.__qualname__))
Ethan Furman019f0a02018-09-12 11:43:34 -0700611 if result is None and exc is None:
612 raise ve_exc
613 elif exc is None:
614 exc = TypeError(
615 'error in %s._missing_: returned %r instead of None or a valid member'
616 % (cls.__name__, result)
617 )
618 exc.__context__ = ve_exc
619 raise exc
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700620
Ethan Furmanc16595e2016-09-10 23:36:59 -0700621 def _generate_next_value_(name, start, count, last_values):
622 for last_value in reversed(last_values):
623 try:
624 return last_value + 1
625 except TypeError:
626 pass
627 else:
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700628 return start
Ethan Furmanc16595e2016-09-10 23:36:59 -0700629
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700630 @classmethod
631 def _missing_(cls, value):
Ethan Furmanc95ad7a2020-09-16 10:26:50 -0700632 return None
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700633
634 def __repr__(self):
635 return "<%s.%s: %r>" % (
Ethan Furman520ad572013-07-19 19:47:21 -0700636 self.__class__.__name__, self._name_, self._value_)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700637
638 def __str__(self):
Ethan Furman520ad572013-07-19 19:47:21 -0700639 return "%s.%s" % (self.__class__.__name__, self._name_)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700640
Ethan Furman388a3922013-08-12 06:51:41 -0700641 def __dir__(self):
Ethan Furman0ae550b2014-10-14 08:58:32 -0700642 added_behavior = [
643 m
644 for cls in self.__class__.mro()
645 for m in cls.__dict__
Ethan Furman354ecf12015-03-11 08:43:12 -0700646 if m[0] != '_' and m not in self._member_map_
Ethan Furman0ae550b2014-10-14 08:58:32 -0700647 ]
Ethan Furmanec5f8eb2014-10-21 13:40:35 -0700648 return (['__class__', '__doc__', '__module__'] + added_behavior)
Ethan Furman388a3922013-08-12 06:51:41 -0700649
Ethan Furmanec15a822013-08-31 19:17:41 -0700650 def __format__(self, format_spec):
651 # mixed-in Enums should use the mixed-in type's __format__, otherwise
652 # we can get strange results with the Enum name showing up instead of
653 # the value
654
thatneat2f19e822019-07-04 11:28:37 -0700655 # pure Enum branch, or branch with __str__ explicitly overridden
656 str_overridden = type(self).__str__ != Enum.__str__
657 if self._member_type_ is object or str_overridden:
Ethan Furmanec15a822013-08-31 19:17:41 -0700658 cls = str
659 val = str(self)
660 # mix-in branch
661 else:
662 cls = self._member_type_
Ethan Furman0081f232014-09-16 17:31:23 -0700663 val = self._value_
Ethan Furmanec15a822013-08-31 19:17:41 -0700664 return cls.__format__(val, format_spec)
665
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700666 def __hash__(self):
Ethan Furman520ad572013-07-19 19:47:21 -0700667 return hash(self._name_)
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700668
Ethan Furmanca1b7942014-02-08 11:36:27 -0800669 def __reduce_ex__(self, proto):
Ethan Furmandc870522014-02-18 12:37:12 -0800670 return self.__class__, (self._value_, )
Ethan Furmanca1b7942014-02-08 11:36:27 -0800671
Ethan Furman33918c12013-09-27 23:02:02 -0700672 # DynamicClassAttribute is used to provide access to the `name` and
673 # `value` properties of enum members while keeping some measure of
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700674 # protection from modification, while still allowing for an enumeration
675 # to have members named `name` and `value`. This works because enumeration
676 # members are not set directly on the enum class -- __getattr__ is
677 # used to look them up.
678
Ethan Furmane03ea372013-09-25 07:14:41 -0700679 @DynamicClassAttribute
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700680 def name(self):
Ethan Furmanc850f342013-09-15 16:59:35 -0700681 """The name of the Enum member."""
Ethan Furman520ad572013-07-19 19:47:21 -0700682 return self._name_
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700683
Ethan Furmane03ea372013-09-25 07:14:41 -0700684 @DynamicClassAttribute
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700685 def value(self):
Ethan Furmanc850f342013-09-15 16:59:35 -0700686 """The value of the Enum member."""
Ethan Furman520ad572013-07-19 19:47:21 -0700687 return self._value_
Ethan Furman6b3d64a2013-06-14 16:55:46 -0700688
689
690class IntEnum(int, Enum):
691 """Enum where members are also (and must be) ints"""
Ethan Furmanf24bb352013-07-18 17:05:39 -0700692
693
Ethan Furman24e837f2015-03-18 17:27:57 -0700694def _reduce_ex_by_name(self, proto):
695 return self.name
696
Ethan Furman65a5a472016-09-01 23:55:19 -0700697class Flag(Enum):
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700698 """Support for flags"""
Ethan Furmanc16595e2016-09-10 23:36:59 -0700699
700 def _generate_next_value_(name, start, count, last_values):
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700701 """
702 Generate the next value when not given.
703
704 name: the name of the member
HongWeipengbb16fb22019-09-21 13:22:54 +0800705 start: the initial start value or None
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700706 count: the number of existing members
707 last_value: the last value assigned or None
708 """
709 if not count:
710 return start if start is not None else 1
Ethan Furmanc16595e2016-09-10 23:36:59 -0700711 for last_value in reversed(last_values):
712 try:
713 high_bit = _high_bit(last_value)
714 break
Ethan Furman3515dcc2016-09-18 13:15:41 -0700715 except Exception:
Ethan Furmanc16595e2016-09-10 23:36:59 -0700716 raise TypeError('Invalid Flag value: %r' % last_value) from None
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700717 return 2 ** (high_bit+1)
718
719 @classmethod
720 def _missing_(cls, value):
721 original_value = value
722 if value < 0:
723 value = ~value
724 possible_member = cls._create_pseudo_member_(value)
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700725 if original_value < 0:
726 possible_member = ~possible_member
727 return possible_member
728
729 @classmethod
730 def _create_pseudo_member_(cls, value):
Ethan Furman3515dcc2016-09-18 13:15:41 -0700731 """
732 Create a composite member iff value contains only members.
733 """
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700734 pseudo_member = cls._value2member_map_.get(value, None)
735 if pseudo_member is None:
Ethan Furman3515dcc2016-09-18 13:15:41 -0700736 # verify all bits are accounted for
737 _, extra_flags = _decompose(cls, value)
738 if extra_flags:
Walter Dörwald323842c2019-07-18 20:37:13 +0200739 raise ValueError("%r is not a valid %s" % (value, cls.__qualname__))
Ethan Furman3515dcc2016-09-18 13:15:41 -0700740 # construct a singleton enum pseudo-member
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700741 pseudo_member = object.__new__(cls)
742 pseudo_member._name_ = None
743 pseudo_member._value_ = value
Ethan Furman28cf6632017-01-24 12:12:06 -0800744 # use setdefault in case another thread already created a composite
745 # with this value
746 pseudo_member = cls._value2member_map_.setdefault(value, pseudo_member)
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700747 return pseudo_member
748
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700749 def __contains__(self, other):
750 if not isinstance(other, self.__class__):
Rahul Jha94306522018-09-10 23:51:04 +0530751 raise TypeError(
752 "unsupported operand type(s) for 'in': '%s' and '%s'" % (
753 type(other).__qualname__, self.__class__.__qualname__))
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700754 return other._value_ & self._value_ == other._value_
755
Ethan Furman7219e272020-09-16 13:01:00 -0700756 def __iter__(self):
757 members, extra_flags = _decompose(self.__class__, self.value)
758 return (m for m in members if m._value_ != 0)
759
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700760 def __repr__(self):
761 cls = self.__class__
762 if self._name_ is not None:
763 return '<%s.%s: %r>' % (cls.__name__, self._name_, self._value_)
Ethan Furman3515dcc2016-09-18 13:15:41 -0700764 members, uncovered = _decompose(cls, self._value_)
Ethan Furman27682d22016-09-04 11:39:01 -0700765 return '<%s.%s: %r>' % (
766 cls.__name__,
767 '|'.join([str(m._name_ or m._value_) for m in members]),
768 self._value_,
769 )
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700770
771 def __str__(self):
772 cls = self.__class__
773 if self._name_ is not None:
774 return '%s.%s' % (cls.__name__, self._name_)
Ethan Furman3515dcc2016-09-18 13:15:41 -0700775 members, uncovered = _decompose(cls, self._value_)
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700776 if len(members) == 1 and members[0]._name_ is None:
777 return '%s.%r' % (cls.__name__, members[0]._value_)
778 else:
779 return '%s.%s' % (
780 cls.__name__,
781 '|'.join([str(m._name_ or m._value_) for m in members]),
782 )
783
Ethan Furman25d94bb2016-09-02 16:32:32 -0700784 def __bool__(self):
785 return bool(self._value_)
786
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700787 def __or__(self, other):
788 if not isinstance(other, self.__class__):
789 return NotImplemented
790 return self.__class__(self._value_ | other._value_)
791
792 def __and__(self, other):
793 if not isinstance(other, self.__class__):
794 return NotImplemented
795 return self.__class__(self._value_ & other._value_)
796
797 def __xor__(self, other):
798 if not isinstance(other, self.__class__):
799 return NotImplemented
800 return self.__class__(self._value_ ^ other._value_)
801
802 def __invert__(self):
Ethan Furman3515dcc2016-09-18 13:15:41 -0700803 members, uncovered = _decompose(self.__class__, self._value_)
Serhiy Storchaka81108372017-09-26 00:55:55 +0300804 inverted = self.__class__(0)
805 for m in self.__class__:
806 if m not in members and not (m._value_ & self._value_):
807 inverted = inverted | m
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700808 return self.__class__(inverted)
809
810
Ethan Furman65a5a472016-09-01 23:55:19 -0700811class IntFlag(int, Flag):
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700812 """Support for integer-based Flags"""
813
814 @classmethod
Ethan Furman3515dcc2016-09-18 13:15:41 -0700815 def _missing_(cls, value):
816 if not isinstance(value, int):
Walter Dörwald323842c2019-07-18 20:37:13 +0200817 raise ValueError("%r is not a valid %s" % (value, cls.__qualname__))
Ethan Furman3515dcc2016-09-18 13:15:41 -0700818 new_member = cls._create_pseudo_member_(value)
819 return new_member
820
821 @classmethod
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700822 def _create_pseudo_member_(cls, value):
823 pseudo_member = cls._value2member_map_.get(value, None)
824 if pseudo_member is None:
Ethan Furman3515dcc2016-09-18 13:15:41 -0700825 need_to_create = [value]
826 # get unaccounted for bits
827 _, extra_flags = _decompose(cls, value)
828 # timer = 10
829 while extra_flags:
830 # timer -= 1
831 bit = _high_bit(extra_flags)
832 flag_value = 2 ** bit
833 if (flag_value not in cls._value2member_map_ and
834 flag_value not in need_to_create
835 ):
836 need_to_create.append(flag_value)
837 if extra_flags == -flag_value:
838 extra_flags = 0
839 else:
840 extra_flags ^= flag_value
841 for value in reversed(need_to_create):
842 # construct singleton pseudo-members
843 pseudo_member = int.__new__(cls, value)
844 pseudo_member._name_ = None
845 pseudo_member._value_ = value
Ethan Furman28cf6632017-01-24 12:12:06 -0800846 # use setdefault in case another thread already created a composite
847 # with this value
848 pseudo_member = cls._value2member_map_.setdefault(value, pseudo_member)
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700849 return pseudo_member
850
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700851 def __or__(self, other):
852 if not isinstance(other, (self.__class__, int)):
853 return NotImplemented
Ethan Furman3515dcc2016-09-18 13:15:41 -0700854 result = self.__class__(self._value_ | self.__class__(other)._value_)
855 return result
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700856
857 def __and__(self, other):
858 if not isinstance(other, (self.__class__, int)):
859 return NotImplemented
860 return self.__class__(self._value_ & self.__class__(other)._value_)
861
862 def __xor__(self, other):
863 if not isinstance(other, (self.__class__, int)):
864 return NotImplemented
865 return self.__class__(self._value_ ^ self.__class__(other)._value_)
866
867 __ror__ = __or__
868 __rand__ = __and__
869 __rxor__ = __xor__
870
871 def __invert__(self):
Ethan Furman3515dcc2016-09-18 13:15:41 -0700872 result = self.__class__(~self._value_)
873 return result
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700874
875
876def _high_bit(value):
Ethan Furman04439532016-09-02 15:50:21 -0700877 """returns index of highest bit, or -1 if value is zero or negative"""
Ethan Furman3515dcc2016-09-18 13:15:41 -0700878 return value.bit_length() - 1
Ethan Furmanee47e5c2016-08-31 00:12:15 -0700879
Ethan Furmanf24bb352013-07-18 17:05:39 -0700880def unique(enumeration):
881 """Class decorator for enumerations ensuring unique member values."""
882 duplicates = []
883 for name, member in enumeration.__members__.items():
884 if name != member.name:
885 duplicates.append((name, member.name))
886 if duplicates:
887 alias_details = ', '.join(
888 ["%s -> %s" % (alias, name) for (alias, name) in duplicates])
889 raise ValueError('duplicate values found in %r: %s' %
890 (enumeration, alias_details))
891 return enumeration
Ethan Furman3515dcc2016-09-18 13:15:41 -0700892
893def _decompose(flag, value):
894 """Extract all members from the value."""
895 # _decompose is only called if the value is not named
896 not_covered = value
897 negative = value < 0
Ethan Furman3515dcc2016-09-18 13:15:41 -0700898 members = []
HongWeipeng0b41a922019-11-27 06:36:02 +0800899 for member in flag:
900 member_value = member.value
Ethan Furman3515dcc2016-09-18 13:15:41 -0700901 if member_value and member_value & value == member_value:
902 members.append(member)
903 not_covered &= ~member_value
HongWeipeng0b41a922019-11-27 06:36:02 +0800904 if not negative:
905 tmp = not_covered
906 while tmp:
907 flag_value = 2 ** _high_bit(tmp)
908 if flag_value in flag._value2member_map_:
909 members.append(flag._value2member_map_[flag_value])
910 not_covered &= ~flag_value
911 tmp &= ~flag_value
Ethan Furman3515dcc2016-09-18 13:15:41 -0700912 if not members and value in flag._value2member_map_:
913 members.append(flag._value2member_map_[value])
914 members.sort(key=lambda m: m._value_, reverse=True)
915 if len(members) > 1 and members[0].value == value:
916 # we have the breakdown, don't need the value member itself
917 members.pop(0)
918 return members, not_covered