1 import sys
2 import builtins as bltns
3 from types import MappingProxyType, DynamicClassAttribute
4 from operator import or_ as _or_
5 from functools import reduce
6
7
8 __all__ = [
9 'EnumType', 'EnumMeta',
10 'Enum', 'IntEnum', 'StrEnum', 'Flag', 'IntFlag', 'ReprEnum',
11 'auto', 'unique', 'property', 'verify', 'member', 'nonmember',
12 'FlagBoundary', 'STRICT', 'CONFORM', 'EJECT', 'KEEP',
13 'global_flag_repr', 'global_enum_repr', 'global_str', 'global_enum',
14 'EnumCheck', 'CONTINUOUS', 'NAMED_FLAGS', 'UNIQUE',
15 'pickle_by_global_name', 'pickle_by_enum_name',
16 ]
17
18
19 # Dummy value for Enum and Flag as there are explicit checks for them
20 # before they have been created.
21 # This is also why there are checks in EnumType like `if Enum is not None`
22 Enum = Flag = EJECT = _stdlib_enums = ReprEnum = None
23
24 class ESC[4;38;5;81mnonmember(ESC[4;38;5;149mobject):
25 """
26 Protects item from becoming an Enum member during class creation.
27 """
28 def __init__(self, value):
29 self.value = value
30
31 class ESC[4;38;5;81mmember(ESC[4;38;5;149mobject):
32 """
33 Forces item to become an Enum member during class creation.
34 """
35 def __init__(self, value):
36 self.value = value
37
38 def _is_descriptor(obj):
39 """
40 Returns True if obj is a descriptor, False otherwise.
41 """
42 return (
43 hasattr(obj, '__get__') or
44 hasattr(obj, '__set__') or
45 hasattr(obj, '__delete__')
46 )
47
48 def _is_dunder(name):
49 """
50 Returns True if a __dunder__ name, False otherwise.
51 """
52 return (
53 len(name) > 4 and
54 name[:2] == name[-2:] == '__' and
55 name[2] != '_' and
56 name[-3] != '_'
57 )
58
59 def _is_sunder(name):
60 """
61 Returns True if a _sunder_ name, False otherwise.
62 """
63 return (
64 len(name) > 2 and
65 name[0] == name[-1] == '_' and
66 name[1:2] != '_' and
67 name[-2:-1] != '_'
68 )
69
70 def _is_internal_class(cls_name, obj):
71 # do not use `re` as `re` imports `enum`
72 if not isinstance(obj, type):
73 return False
74 qualname = getattr(obj, '__qualname__', '')
75 s_pattern = cls_name + '.' + getattr(obj, '__name__', '')
76 e_pattern = '.' + s_pattern
77 return qualname == s_pattern or qualname.endswith(e_pattern)
78
79 def _is_private(cls_name, name):
80 # do not use `re` as `re` imports `enum`
81 pattern = '_%s__' % (cls_name, )
82 pat_len = len(pattern)
83 if (
84 len(name) > pat_len
85 and name.startswith(pattern)
86 and name[pat_len:pat_len+1] != ['_']
87 and (name[-1] != '_' or name[-2] != '_')
88 ):
89 return True
90 else:
91 return False
92
93 def _is_single_bit(num):
94 """
95 True if only one bit set in num (should be an int)
96 """
97 if num == 0:
98 return False
99 num &= num - 1
100 return num == 0
101
102 def _make_class_unpicklable(obj):
103 """
104 Make the given obj un-picklable.
105
106 obj should be either a dictionary, or an Enum
107 """
108 def _break_on_call_reduce(self, proto):
109 raise TypeError('%r cannot be pickled' % self)
110 if isinstance(obj, dict):
111 obj['__reduce_ex__'] = _break_on_call_reduce
112 obj['__module__'] = '<unknown>'
113 else:
114 setattr(obj, '__reduce_ex__', _break_on_call_reduce)
115 setattr(obj, '__module__', '<unknown>')
116
117 def _iter_bits_lsb(num):
118 # num must be a positive integer
119 original = num
120 if isinstance(num, Enum):
121 num = num.value
122 if num < 0:
123 raise ValueError('%r is not a positive integer' % original)
124 while num:
125 b = num & (~num + 1)
126 yield b
127 num ^= b
128
129 def show_flag_values(value):
130 return list(_iter_bits_lsb(value))
131
132 def bin(num, max_bits=None):
133 """
134 Like built-in bin(), except negative values are represented in
135 twos-compliment, and the leading bit always indicates sign
136 (0=positive, 1=negative).
137
138 >>> bin(10)
139 '0b0 1010'
140 >>> bin(~10) # ~10 is -11
141 '0b1 0101'
142 """
143
144 ceiling = 2 ** (num).bit_length()
145 if num >= 0:
146 s = bltns.bin(num + ceiling).replace('1', '0', 1)
147 else:
148 s = bltns.bin(~num ^ (ceiling - 1) + ceiling)
149 sign = s[:3]
150 digits = s[3:]
151 if max_bits is not None:
152 if len(digits) < max_bits:
153 digits = (sign[-1] * max_bits + digits)[-max_bits:]
154 return "%s %s" % (sign, digits)
155
156 def _dedent(text):
157 """
158 Like textwrap.dedent. Rewritten because we cannot import textwrap.
159 """
160 lines = text.split('\n')
161 blanks = 0
162 for i, ch in enumerate(lines[0]):
163 if ch != ' ':
164 break
165 for j, l in enumerate(lines):
166 lines[j] = l[i:]
167 return '\n'.join(lines)
168
169 class ESC[4;38;5;81m_auto_null:
170 def __repr__(self):
171 return '_auto_null'
172 _auto_null = _auto_null()
173
174 class ESC[4;38;5;81mauto:
175 """
176 Instances are replaced with an appropriate value in Enum class suites.
177 """
178 def __init__(self, value=_auto_null):
179 self.value = value
180
181 def __repr__(self):
182 return "auto(%r)" % self.value
183
184 class ESC[4;38;5;81mproperty(ESC[4;38;5;149mDynamicClassAttribute):
185 """
186 This is a descriptor, used to define attributes that act differently
187 when accessed through an enum member and through an enum class.
188 Instance access is the same as property(), but access to an attribute
189 through the enum class will instead look in the class' _member_map_ for
190 a corresponding enum member.
191 """
192
193 member = None
194 _attr_type = None
195 _cls_type = None
196
197 def __get__(self, instance, ownerclass=None):
198 if instance is None:
199 if self.member is not None:
200 return self.member
201 else:
202 raise AttributeError(
203 '%r has no attribute %r' % (ownerclass, self.name)
204 )
205 if self.fget is not None:
206 # use previous enum.property
207 return self.fget(instance)
208 elif self._attr_type == 'attr':
209 # look up previous attibute
210 return getattr(self._cls_type, self.name)
211 elif self._attr_type == 'desc':
212 # use previous descriptor
213 return getattr(instance._value_, self.name)
214 # look for a member by this name.
215 try:
216 return ownerclass._member_map_[self.name]
217 except KeyError:
218 raise AttributeError(
219 '%r has no attribute %r' % (ownerclass, self.name)
220 ) from None
221
222 def __set__(self, instance, value):
223 if self.fset is not None:
224 return self.fset(instance, value)
225 raise AttributeError(
226 "<enum %r> cannot set attribute %r" % (self.clsname, self.name)
227 )
228
229 def __delete__(self, instance):
230 if self.fdel is not None:
231 return self.fdel(instance)
232 raise AttributeError(
233 "<enum %r> cannot delete attribute %r" % (self.clsname, self.name)
234 )
235
236 def __set_name__(self, ownerclass, name):
237 self.name = name
238 self.clsname = ownerclass.__name__
239
240
241 class ESC[4;38;5;81m_proto_member:
242 """
243 intermediate step for enum members between class execution and final creation
244 """
245
246 def __init__(self, value):
247 self.value = value
248
249 def __set_name__(self, enum_class, member_name):
250 """
251 convert each quasi-member into an instance of the new enum class
252 """
253 # first step: remove ourself from enum_class
254 delattr(enum_class, member_name)
255 # second step: create member based on enum_class
256 value = self.value
257 if not isinstance(value, tuple):
258 args = (value, )
259 else:
260 args = value
261 if enum_class._member_type_ is tuple: # special case for tuple enums
262 args = (args, ) # wrap it one more time
263 if not enum_class._use_args_:
264 enum_member = enum_class._new_member_(enum_class)
265 else:
266 enum_member = enum_class._new_member_(enum_class, *args)
267 if not hasattr(enum_member, '_value_'):
268 if enum_class._member_type_ is object:
269 enum_member._value_ = value
270 else:
271 try:
272 enum_member._value_ = enum_class._member_type_(*args)
273 except Exception as exc:
274 new_exc = TypeError(
275 '_value_ not set in __new__, unable to create it'
276 )
277 new_exc.__cause__ = exc
278 raise new_exc
279 value = enum_member._value_
280 enum_member._name_ = member_name
281 enum_member.__objclass__ = enum_class
282 enum_member.__init__(*args)
283 enum_member._sort_order_ = len(enum_class._member_names_)
284
285 if Flag is not None and issubclass(enum_class, Flag):
286 enum_class._flag_mask_ |= value
287 if _is_single_bit(value):
288 enum_class._singles_mask_ |= value
289 enum_class._all_bits_ = 2 ** ((enum_class._flag_mask_).bit_length()) - 1
290
291 # If another member with the same value was already defined, the
292 # new member becomes an alias to the existing one.
293 try:
294 try:
295 # try to do a fast lookup to avoid the quadratic loop
296 enum_member = enum_class._value2member_map_[value]
297 except TypeError:
298 for name, canonical_member in enum_class._member_map_.items():
299 if canonical_member._value_ == value:
300 enum_member = canonical_member
301 break
302 else:
303 raise KeyError
304 except KeyError:
305 # this could still be an alias if the value is multi-bit and the
306 # class is a flag class
307 if (
308 Flag is None
309 or not issubclass(enum_class, Flag)
310 ):
311 # no other instances found, record this member in _member_names_
312 enum_class._member_names_.append(member_name)
313 elif (
314 Flag is not None
315 and issubclass(enum_class, Flag)
316 and _is_single_bit(value)
317 ):
318 # no other instances found, record this member in _member_names_
319 enum_class._member_names_.append(member_name)
320 # if necessary, get redirect in place and then add it to _member_map_
321 found_descriptor = None
322 descriptor_type = None
323 class_type = None
324 for base in enum_class.__mro__[1:]:
325 attr = base.__dict__.get(member_name)
326 if attr is not None:
327 if isinstance(attr, (property, DynamicClassAttribute)):
328 found_descriptor = attr
329 class_type = base
330 descriptor_type = 'enum'
331 break
332 elif _is_descriptor(attr):
333 found_descriptor = attr
334 descriptor_type = descriptor_type or 'desc'
335 class_type = class_type or base
336 continue
337 else:
338 descriptor_type = 'attr'
339 class_type = base
340 if found_descriptor:
341 redirect = property()
342 redirect.member = enum_member
343 redirect.__set_name__(enum_class, member_name)
344 if descriptor_type in ('enum','desc'):
345 # earlier descriptor found; copy fget, fset, fdel to this one.
346 redirect.fget = getattr(found_descriptor, 'fget', None)
347 redirect._get = getattr(found_descriptor, '__get__', None)
348 redirect.fset = getattr(found_descriptor, 'fset', None)
349 redirect._set = getattr(found_descriptor, '__set__', None)
350 redirect.fdel = getattr(found_descriptor, 'fdel', None)
351 redirect._del = getattr(found_descriptor, '__delete__', None)
352 redirect._attr_type = descriptor_type
353 redirect._cls_type = class_type
354 setattr(enum_class, member_name, redirect)
355 else:
356 setattr(enum_class, member_name, enum_member)
357 # now add to _member_map_ (even aliases)
358 enum_class._member_map_[member_name] = enum_member
359 try:
360 # This may fail if value is not hashable. We can't add the value
361 # to the map, and by-value lookups for this value will be
362 # linear.
363 enum_class._value2member_map_.setdefault(value, enum_member)
364 except TypeError:
365 # keep track of the value in a list so containment checks are quick
366 enum_class._unhashable_values_.append(value)
367
368
369 class ESC[4;38;5;81m_EnumDict(ESC[4;38;5;149mdict):
370 """
371 Track enum member order and ensure member names are not reused.
372
373 EnumType will use the names found in self._member_names as the
374 enumeration member names.
375 """
376 def __init__(self):
377 super().__init__()
378 self._member_names = {} # use a dict to keep insertion order
379 self._last_values = []
380 self._ignore = []
381 self._auto_called = False
382
383 def __setitem__(self, key, value):
384 """
385 Changes anything not dundered or not a descriptor.
386
387 If an enum member name is used twice, an error is raised; duplicate
388 values are not checked for.
389
390 Single underscore (sunder) names are reserved.
391 """
392 if _is_internal_class(self._cls_name, value):
393 import warnings
394 warnings.warn(
395 "In 3.13 classes created inside an enum will not become a member. "
396 "Use the `member` decorator to keep the current behavior.",
397 DeprecationWarning,
398 stacklevel=2,
399 )
400 if _is_private(self._cls_name, key):
401 # also do nothing, name will be a normal attribute
402 pass
403 elif _is_sunder(key):
404 if key not in (
405 '_order_',
406 '_generate_next_value_', '_numeric_repr_', '_missing_', '_ignore_',
407 '_iter_member_', '_iter_member_by_value_', '_iter_member_by_def_',
408 ):
409 raise ValueError(
410 '_sunder_ names, such as %r, are reserved for future Enum use'
411 % (key, )
412 )
413 if key == '_generate_next_value_':
414 # check if members already defined as auto()
415 if self._auto_called:
416 raise TypeError("_generate_next_value_ must be defined before members")
417 _gnv = value.__func__ if isinstance(value, staticmethod) else value
418 setattr(self, '_generate_next_value', _gnv)
419 elif key == '_ignore_':
420 if isinstance(value, str):
421 value = value.replace(',',' ').split()
422 else:
423 value = list(value)
424 self._ignore = value
425 already = set(value) & set(self._member_names)
426 if already:
427 raise ValueError(
428 '_ignore_ cannot specify already set names: %r'
429 % (already, )
430 )
431 elif _is_dunder(key):
432 if key == '__order__':
433 key = '_order_'
434 elif key in self._member_names:
435 # descriptor overwriting an enum?
436 raise TypeError('%r already defined as %r' % (key, self[key]))
437 elif key in self._ignore:
438 pass
439 elif isinstance(value, nonmember):
440 # unwrap value here; it won't be processed by the below `else`
441 value = value.value
442 elif _is_descriptor(value):
443 pass
444 # TODO: uncomment next three lines in 3.13
445 # elif _is_internal_class(self._cls_name, value):
446 # # do nothing, name will be a normal attribute
447 # pass
448 else:
449 if key in self:
450 # enum overwriting a descriptor?
451 raise TypeError('%r already defined as %r' % (key, self[key]))
452 elif isinstance(value, member):
453 # unwrap value here -- it will become a member
454 value = value.value
455 non_auto_store = True
456 single = False
457 if isinstance(value, auto):
458 single = True
459 value = (value, )
460 if type(value) is tuple and any(isinstance(v, auto) for v in value):
461 # insist on an actual tuple, no subclasses, in keeping with only supporting
462 # top-level auto() usage (not contained in any other data structure)
463 auto_valued = []
464 for v in value:
465 if isinstance(v, auto):
466 non_auto_store = False
467 if v.value == _auto_null:
468 v.value = self._generate_next_value(
469 key, 1, len(self._member_names), self._last_values[:],
470 )
471 self._auto_called = True
472 v = v.value
473 self._last_values.append(v)
474 auto_valued.append(v)
475 if single:
476 value = auto_valued[0]
477 else:
478 value = tuple(auto_valued)
479 self._member_names[key] = None
480 if non_auto_store:
481 self._last_values.append(value)
482 super().__setitem__(key, value)
483
484 def update(self, members, **more_members):
485 try:
486 for name in members.keys():
487 self[name] = members[name]
488 except AttributeError:
489 for name, value in members:
490 self[name] = value
491 for name, value in more_members.items():
492 self[name] = value
493
494
495 class ESC[4;38;5;81mEnumType(ESC[4;38;5;149mtype):
496 """
497 Metaclass for Enum
498 """
499
500 @classmethod
501 def __prepare__(metacls, cls, bases, **kwds):
502 # check that previous enum members do not exist
503 metacls._check_for_existing_members_(cls, bases)
504 # create the namespace dict
505 enum_dict = _EnumDict()
506 enum_dict._cls_name = cls
507 # inherit previous flags and _generate_next_value_ function
508 member_type, first_enum = metacls._get_mixins_(cls, bases)
509 if first_enum is not None:
510 enum_dict['_generate_next_value_'] = getattr(
511 first_enum, '_generate_next_value_', None,
512 )
513 return enum_dict
514
515 def __new__(metacls, cls, bases, classdict, *, boundary=None, _simple=False, **kwds):
516 # an Enum class is final once enumeration items have been defined; it
517 # cannot be mixed with other types (int, float, etc.) if it has an
518 # inherited __new__ unless a new __new__ is defined (or the resulting
519 # class will fail).
520 #
521 if _simple:
522 return super().__new__(metacls, cls, bases, classdict, **kwds)
523 #
524 # remove any keys listed in _ignore_
525 classdict.setdefault('_ignore_', []).append('_ignore_')
526 ignore = classdict['_ignore_']
527 for key in ignore:
528 classdict.pop(key, None)
529 #
530 # grab member names
531 member_names = classdict._member_names
532 #
533 # check for illegal enum names (any others?)
534 invalid_names = set(member_names) & {'mro', ''}
535 if invalid_names:
536 raise ValueError('invalid enum member name(s) %s' % (
537 ','.join(repr(n) for n in invalid_names)
538 ))
539 #
540 # adjust the sunders
541 _order_ = classdict.pop('_order_', None)
542 _gnv = classdict.get('_generate_next_value_')
543 if _gnv is not None and type(_gnv) is not staticmethod:
544 _gnv = staticmethod(_gnv)
545 # convert to normal dict
546 classdict = dict(classdict.items())
547 if _gnv is not None:
548 classdict['_generate_next_value_'] = _gnv
549 #
550 # data type of member and the controlling Enum class
551 member_type, first_enum = metacls._get_mixins_(cls, bases)
552 __new__, save_new, use_args = metacls._find_new_(
553 classdict, member_type, first_enum,
554 )
555 classdict['_new_member_'] = __new__
556 classdict['_use_args_'] = use_args
557 #
558 # convert future enum members into temporary _proto_members
559 for name in member_names:
560 value = classdict[name]
561 classdict[name] = _proto_member(value)
562 #
563 # house-keeping structures
564 classdict['_member_names_'] = []
565 classdict['_member_map_'] = {}
566 classdict['_value2member_map_'] = {}
567 classdict['_unhashable_values_'] = []
568 classdict['_member_type_'] = member_type
569 # now set the __repr__ for the value
570 classdict['_value_repr_'] = metacls._find_data_repr_(cls, bases)
571 #
572 # Flag structures (will be removed if final class is not a Flag
573 classdict['_boundary_'] = (
574 boundary
575 or getattr(first_enum, '_boundary_', None)
576 )
577 classdict['_flag_mask_'] = 0
578 classdict['_singles_mask_'] = 0
579 classdict['_all_bits_'] = 0
580 classdict['_inverted_'] = None
581 try:
582 exc = None
583 enum_class = super().__new__(metacls, cls, bases, classdict, **kwds)
584 except RuntimeError as e:
585 # any exceptions raised by member.__new__ will get converted to a
586 # RuntimeError, so get that original exception back and raise it instead
587 exc = e.__cause__ or e
588 if exc is not None:
589 raise exc
590 #
591 # update classdict with any changes made by __init_subclass__
592 classdict.update(enum_class.__dict__)
593 #
594 # double check that repr and friends are not the mixin's or various
595 # things break (such as pickle)
596 # however, if the method is defined in the Enum itself, don't replace
597 # it
598 #
599 # Also, special handling for ReprEnum
600 if ReprEnum is not None and ReprEnum in bases:
601 if member_type is object:
602 raise TypeError(
603 'ReprEnum subclasses must be mixed with a data type (i.e.'
604 ' int, str, float, etc.)'
605 )
606 if '__format__' not in classdict:
607 enum_class.__format__ = member_type.__format__
608 classdict['__format__'] = enum_class.__format__
609 if '__str__' not in classdict:
610 method = member_type.__str__
611 if method is object.__str__:
612 # if member_type does not define __str__, object.__str__ will use
613 # its __repr__ instead, so we'll also use its __repr__
614 method = member_type.__repr__
615 enum_class.__str__ = method
616 classdict['__str__'] = enum_class.__str__
617 for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'):
618 if name not in classdict:
619 # check for mixin overrides before replacing
620 enum_method = getattr(first_enum, name)
621 found_method = getattr(enum_class, name)
622 object_method = getattr(object, name)
623 data_type_method = getattr(member_type, name)
624 if found_method in (data_type_method, object_method):
625 setattr(enum_class, name, enum_method)
626 #
627 # for Flag, add __or__, __and__, __xor__, and __invert__
628 if Flag is not None and issubclass(enum_class, Flag):
629 for name in (
630 '__or__', '__and__', '__xor__',
631 '__ror__', '__rand__', '__rxor__',
632 '__invert__'
633 ):
634 if name not in classdict:
635 enum_method = getattr(Flag, name)
636 setattr(enum_class, name, enum_method)
637 classdict[name] = enum_method
638 #
639 # replace any other __new__ with our own (as long as Enum is not None,
640 # anyway) -- again, this is to support pickle
641 if Enum is not None:
642 # if the user defined their own __new__, save it before it gets
643 # clobbered in case they subclass later
644 if save_new:
645 enum_class.__new_member__ = __new__
646 enum_class.__new__ = Enum.__new__
647 #
648 # py3 support for definition order (helps keep py2/py3 code in sync)
649 #
650 # _order_ checking is spread out into three/four steps
651 # - if enum_class is a Flag:
652 # - remove any non-single-bit flags from _order_
653 # - remove any aliases from _order_
654 # - check that _order_ and _member_names_ match
655 #
656 # step 1: ensure we have a list
657 if _order_ is not None:
658 if isinstance(_order_, str):
659 _order_ = _order_.replace(',', ' ').split()
660 #
661 # remove Flag structures if final class is not a Flag
662 if (
663 Flag is None and cls != 'Flag'
664 or Flag is not None and not issubclass(enum_class, Flag)
665 ):
666 delattr(enum_class, '_boundary_')
667 delattr(enum_class, '_flag_mask_')
668 delattr(enum_class, '_singles_mask_')
669 delattr(enum_class, '_all_bits_')
670 delattr(enum_class, '_inverted_')
671 elif Flag is not None and issubclass(enum_class, Flag):
672 # set correct __iter__
673 member_list = [m._value_ for m in enum_class]
674 if member_list != sorted(member_list):
675 enum_class._iter_member_ = enum_class._iter_member_by_def_
676 if _order_:
677 # _order_ step 2: remove any items from _order_ that are not single-bit
678 _order_ = [
679 o
680 for o in _order_
681 if o not in enum_class._member_map_ or _is_single_bit(enum_class[o]._value_)
682 ]
683 #
684 if _order_:
685 # _order_ step 3: remove aliases from _order_
686 _order_ = [
687 o
688 for o in _order_
689 if (
690 o not in enum_class._member_map_
691 or
692 (o in enum_class._member_map_ and o in enum_class._member_names_)
693 )]
694 # _order_ step 4: verify that _order_ and _member_names_ match
695 if _order_ != enum_class._member_names_:
696 raise TypeError(
697 'member order does not match _order_:\n %r\n %r'
698 % (enum_class._member_names_, _order_)
699 )
700 #
701 return enum_class
702
703 def __bool__(cls):
704 """
705 classes/types should always be True.
706 """
707 return True
708
709 def __call__(cls, value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None):
710 """
711 Either returns an existing member, or creates a new enum class.
712
713 This method is used both when an enum class is given a value to match
714 to an enumeration member (i.e. Color(3)) and for the functional API
715 (i.e. Color = Enum('Color', names='RED GREEN BLUE')).
716
717 The value lookup branch is chosen if the enum is final.
718
719 When used for the functional API:
720
721 `value` will be the name of the new class.
722
723 `names` should be either a string of white-space/comma delimited names
724 (values will start at `start`), or an iterator/mapping of name, value pairs.
725
726 `module` should be set to the module this class is being created in;
727 if it is not set, an attempt to find that module will be made, but if
728 it fails the class will not be picklable.
729
730 `qualname` should be set to the actual location this class can be found
731 at in its module; by default it is set to the global scope. If this is
732 not correct, unpickling will fail in some circumstances.
733
734 `type`, if set, will be mixed in as the first base class.
735 """
736 if cls._member_map_:
737 # simple value lookup if members exist
738 if names:
739 value = (value, names) + values
740 return cls.__new__(cls, value)
741 # otherwise, functional API: we're creating a new Enum type
742 if names is None and type is None:
743 # no body? no data-type? possibly wrong usage
744 raise TypeError(
745 f"{cls} has no members; specify `names=()` if you meant to create a new, empty, enum"
746 )
747 return cls._create_(
748 class_name=value,
749 names=names,
750 module=module,
751 qualname=qualname,
752 type=type,
753 start=start,
754 boundary=boundary,
755 )
756
757 def __contains__(cls, value):
758 """Return True if `value` is in `cls`.
759
760 `value` is in `cls` if:
761 1) `value` is a member of `cls`, or
762 2) `value` is the value of one of the `cls`'s members.
763 """
764 if isinstance(value, cls):
765 return True
766 return value in cls._value2member_map_ or value in cls._unhashable_values_
767
768 def __delattr__(cls, attr):
769 # nicer error message when someone tries to delete an attribute
770 # (see issue19025).
771 if attr in cls._member_map_:
772 raise AttributeError("%r cannot delete member %r." % (cls.__name__, attr))
773 super().__delattr__(attr)
774
775 def __dir__(cls):
776 interesting = set([
777 '__class__', '__contains__', '__doc__', '__getitem__',
778 '__iter__', '__len__', '__members__', '__module__',
779 '__name__', '__qualname__',
780 ]
781 + cls._member_names_
782 )
783 if cls._new_member_ is not object.__new__:
784 interesting.add('__new__')
785 if cls.__init_subclass__ is not object.__init_subclass__:
786 interesting.add('__init_subclass__')
787 if cls._member_type_ is object:
788 return sorted(interesting)
789 else:
790 # return whatever mixed-in data type has
791 return sorted(set(dir(cls._member_type_)) | interesting)
792
793 def __getitem__(cls, name):
794 """
795 Return the member matching `name`.
796 """
797 return cls._member_map_[name]
798
799 def __iter__(cls):
800 """
801 Return members in definition order.
802 """
803 return (cls._member_map_[name] for name in cls._member_names_)
804
805 def __len__(cls):
806 """
807 Return the number of members (no aliases)
808 """
809 return len(cls._member_names_)
810
811 @bltns.property
812 def __members__(cls):
813 """
814 Returns a mapping of member name->value.
815
816 This mapping lists all enum members, including aliases. Note that this
817 is a read-only view of the internal mapping.
818 """
819 return MappingProxyType(cls._member_map_)
820
821 def __repr__(cls):
822 if Flag is not None and issubclass(cls, Flag):
823 return "<flag %r>" % cls.__name__
824 else:
825 return "<enum %r>" % cls.__name__
826
827 def __reversed__(cls):
828 """
829 Return members in reverse definition order.
830 """
831 return (cls._member_map_[name] for name in reversed(cls._member_names_))
832
833 def __setattr__(cls, name, value):
834 """
835 Block attempts to reassign Enum members.
836
837 A simple assignment to the class namespace only changes one of the
838 several possible ways to get an Enum member from the Enum class,
839 resulting in an inconsistent Enumeration.
840 """
841 member_map = cls.__dict__.get('_member_map_', {})
842 if name in member_map:
843 raise AttributeError('cannot reassign member %r' % (name, ))
844 super().__setattr__(name, value)
845
846 def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, start=1, boundary=None):
847 """
848 Convenience method to create a new Enum class.
849
850 `names` can be:
851
852 * A string containing member names, separated either with spaces or
853 commas. Values are incremented by 1 from `start`.
854 * An iterable of member names. Values are incremented by 1 from `start`.
855 * An iterable of (member name, value) pairs.
856 * A mapping of member name -> value pairs.
857 """
858 metacls = cls.__class__
859 bases = (cls, ) if type is None else (type, cls)
860 _, first_enum = cls._get_mixins_(class_name, bases)
861 classdict = metacls.__prepare__(class_name, bases)
862
863 # special processing needed for names?
864 if isinstance(names, str):
865 names = names.replace(',', ' ').split()
866 if isinstance(names, (tuple, list)) and names and isinstance(names[0], str):
867 original_names, names = names, []
868 last_values = []
869 for count, name in enumerate(original_names):
870 value = first_enum._generate_next_value_(name, start, count, last_values[:])
871 last_values.append(value)
872 names.append((name, value))
873 if names is None:
874 names = ()
875
876 # Here, names is either an iterable of (name, value) or a mapping.
877 for item in names:
878 if isinstance(item, str):
879 member_name, member_value = item, names[item]
880 else:
881 member_name, member_value = item
882 classdict[member_name] = member_value
883
884 if module is None:
885 try:
886 module = sys._getframemodulename(2)
887 except AttributeError:
888 # Fall back on _getframe if _getframemodulename is missing
889 try:
890 module = sys._getframe(2).f_globals['__name__']
891 except (AttributeError, ValueError, KeyError):
892 pass
893 if module is None:
894 _make_class_unpicklable(classdict)
895 else:
896 classdict['__module__'] = module
897 if qualname is not None:
898 classdict['__qualname__'] = qualname
899
900 return metacls.__new__(metacls, class_name, bases, classdict, boundary=boundary)
901
902 def _convert_(cls, name, module, filter, source=None, *, boundary=None, as_global=False):
903 """
904 Create a new Enum subclass that replaces a collection of global constants
905 """
906 # convert all constants from source (or module) that pass filter() to
907 # a new Enum called name, and export the enum and its members back to
908 # module;
909 # also, replace the __reduce_ex__ method so unpickling works in
910 # previous Python versions
911 module_globals = sys.modules[module].__dict__
912 if source:
913 source = source.__dict__
914 else:
915 source = module_globals
916 # _value2member_map_ is populated in the same order every time
917 # for a consistent reverse mapping of number to name when there
918 # are multiple names for the same number.
919 members = [
920 (name, value)
921 for name, value in source.items()
922 if filter(name)]
923 try:
924 # sort by value
925 members.sort(key=lambda t: (t[1], t[0]))
926 except TypeError:
927 # unless some values aren't comparable, in which case sort by name
928 members.sort(key=lambda t: t[0])
929 body = {t[0]: t[1] for t in members}
930 body['__module__'] = module
931 tmp_cls = type(name, (object, ), body)
932 cls = _simple_enum(etype=cls, boundary=boundary or KEEP)(tmp_cls)
933 if as_global:
934 global_enum(cls)
935 else:
936 sys.modules[cls.__module__].__dict__.update(cls.__members__)
937 module_globals[name] = cls
938 return cls
939
940 @classmethod
941 def _check_for_existing_members_(mcls, class_name, bases):
942 for chain in bases:
943 for base in chain.__mro__:
944 if isinstance(base, EnumType) and base._member_names_:
945 raise TypeError(
946 "<enum %r> cannot extend %r"
947 % (class_name, base)
948 )
949
950 @classmethod
951 def _get_mixins_(mcls, class_name, bases):
952 """
953 Returns the type for creating enum members, and the first inherited
954 enum class.
955
956 bases: the tuple of bases that was given to __new__
957 """
958 if not bases:
959 return object, Enum
960 # ensure final parent class is an Enum derivative, find any concrete
961 # data type, and check that Enum has no members
962 first_enum = bases[-1]
963 if not isinstance(first_enum, EnumType):
964 raise TypeError("new enumerations should be created as "
965 "`EnumName([mixin_type, ...] [data_type,] enum_type)`")
966 member_type = mcls._find_data_type_(class_name, bases) or object
967 return member_type, first_enum
968
969 @classmethod
970 def _find_data_repr_(mcls, class_name, bases):
971 for chain in bases:
972 for base in chain.__mro__:
973 if base is object:
974 continue
975 elif isinstance(base, EnumType):
976 # if we hit an Enum, use it's _value_repr_
977 return base._value_repr_
978 elif '__repr__' in base.__dict__:
979 # this is our data repr
980 # double-check if a dataclass with a default __repr__
981 if (
982 '__dataclass_fields__' in base.__dict__
983 and '__dataclass_params__' in base.__dict__
984 and base.__dict__['__dataclass_params__'].repr
985 ):
986 return _dataclass_repr
987 else:
988 return base.__dict__['__repr__']
989 return None
990
991 @classmethod
992 def _find_data_type_(mcls, class_name, bases):
993 # a datatype has a __new__ method, or a __dataclass_fields__ attribute
994 data_types = set()
995 base_chain = set()
996 for chain in bases:
997 candidate = None
998 for base in chain.__mro__:
999 base_chain.add(base)
1000 if base is object:
1001 continue
1002 elif isinstance(base, EnumType):
1003 if base._member_type_ is not object:
1004 data_types.add(base._member_type_)
1005 break
1006 elif '__new__' in base.__dict__ or '__dataclass_fields__' in base.__dict__:
1007 data_types.add(candidate or base)
1008 break
1009 else:
1010 candidate = candidate or base
1011 if len(data_types) > 1:
1012 raise TypeError('too many data types for %r: %r' % (class_name, data_types))
1013 elif data_types:
1014 return data_types.pop()
1015 else:
1016 return None
1017
1018 @classmethod
1019 def _find_new_(mcls, classdict, member_type, first_enum):
1020 """
1021 Returns the __new__ to be used for creating the enum members.
1022
1023 classdict: the class dictionary given to __new__
1024 member_type: the data type whose __new__ will be used by default
1025 first_enum: enumeration to check for an overriding __new__
1026 """
1027 # now find the correct __new__, checking to see of one was defined
1028 # by the user; also check earlier enum classes in case a __new__ was
1029 # saved as __new_member__
1030 __new__ = classdict.get('__new__', None)
1031
1032 # should __new__ be saved as __new_member__ later?
1033 save_new = first_enum is not None and __new__ is not None
1034
1035 if __new__ is None:
1036 # check all possibles for __new_member__ before falling back to
1037 # __new__
1038 for method in ('__new_member__', '__new__'):
1039 for possible in (member_type, first_enum):
1040 target = getattr(possible, method, None)
1041 if target not in {
1042 None,
1043 None.__new__,
1044 object.__new__,
1045 Enum.__new__,
1046 }:
1047 __new__ = target
1048 break
1049 if __new__ is not None:
1050 break
1051 else:
1052 __new__ = object.__new__
1053
1054 # if a non-object.__new__ is used then whatever value/tuple was
1055 # assigned to the enum member name will be passed to __new__ and to the
1056 # new enum member's __init__
1057 if first_enum is None or __new__ in (Enum.__new__, object.__new__):
1058 use_args = False
1059 else:
1060 use_args = True
1061 return __new__, save_new, use_args
1062 EnumMeta = EnumType
1063
1064
1065 class ESC[4;38;5;81mEnum(metaclass=ESC[4;38;5;149mEnumType):
1066 """
1067 Create a collection of name/value pairs.
1068
1069 Example enumeration:
1070
1071 >>> class Color(Enum):
1072 ... RED = 1
1073 ... BLUE = 2
1074 ... GREEN = 3
1075
1076 Access them by:
1077
1078 - attribute access:
1079
1080 >>> Color.RED
1081 <Color.RED: 1>
1082
1083 - value lookup:
1084
1085 >>> Color(1)
1086 <Color.RED: 1>
1087
1088 - name lookup:
1089
1090 >>> Color['RED']
1091 <Color.RED: 1>
1092
1093 Enumerations can be iterated over, and know how many members they have:
1094
1095 >>> len(Color)
1096 3
1097
1098 >>> list(Color)
1099 [<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]
1100
1101 Methods can be added to enumerations, and members can have their own
1102 attributes -- see the documentation for details.
1103 """
1104
1105 @classmethod
1106 def __signature__(cls):
1107 if cls._member_names_:
1108 return '(*values)'
1109 else:
1110 return '(new_class_name, /, names, *, module=None, qualname=None, type=None, start=1, boundary=None)'
1111
1112 def __new__(cls, value):
1113 # all enum instances are actually created during class construction
1114 # without calling this method; this method is called by the metaclass'
1115 # __call__ (i.e. Color(3) ), and by pickle
1116 if type(value) is cls:
1117 # For lookups like Color(Color.RED)
1118 return value
1119 # by-value search for a matching enum member
1120 # see if it's in the reverse mapping (for hashable values)
1121 try:
1122 return cls._value2member_map_[value]
1123 except KeyError:
1124 # Not found, no need to do long O(n) search
1125 pass
1126 except TypeError:
1127 # not there, now do long search -- O(n) behavior
1128 for member in cls._member_map_.values():
1129 if member._value_ == value:
1130 return member
1131 # still not found -- verify that members exist, in-case somebody got here mistakenly
1132 # (such as via super when trying to override __new__)
1133 if not cls._member_map_:
1134 raise TypeError("%r has no members defined" % cls)
1135 #
1136 # still not found -- try _missing_ hook
1137 try:
1138 exc = None
1139 result = cls._missing_(value)
1140 except Exception as e:
1141 exc = e
1142 result = None
1143 try:
1144 if isinstance(result, cls):
1145 return result
1146 elif (
1147 Flag is not None and issubclass(cls, Flag)
1148 and cls._boundary_ is EJECT and isinstance(result, int)
1149 ):
1150 return result
1151 else:
1152 ve_exc = ValueError("%r is not a valid %s" % (value, cls.__qualname__))
1153 if result is None and exc is None:
1154 raise ve_exc
1155 elif exc is None:
1156 exc = TypeError(
1157 'error in %s._missing_: returned %r instead of None or a valid member'
1158 % (cls.__name__, result)
1159 )
1160 if not isinstance(exc, ValueError):
1161 exc.__context__ = ve_exc
1162 raise exc
1163 finally:
1164 # ensure all variables that could hold an exception are destroyed
1165 exc = None
1166 ve_exc = None
1167
1168 def __init__(self, *args, **kwds):
1169 pass
1170
1171 @staticmethod
1172 def _generate_next_value_(name, start, count, last_values):
1173 """
1174 Generate the next value when not given.
1175
1176 name: the name of the member
1177 start: the initial start value or None
1178 count: the number of existing members
1179 last_values: the list of values assigned
1180 """
1181 if not last_values:
1182 return start
1183 try:
1184 last = last_values[-1]
1185 last_values.sort()
1186 if last == last_values[-1]:
1187 # no difference between old and new methods
1188 return last + 1
1189 else:
1190 # trigger old method (with warning)
1191 raise TypeError
1192 except TypeError:
1193 import warnings
1194 warnings.warn(
1195 "In 3.13 the default `auto()`/`_generate_next_value_` will require all values to be sortable and support adding +1\n"
1196 "and the value returned will be the largest value in the enum incremented by 1",
1197 DeprecationWarning,
1198 stacklevel=3,
1199 )
1200 for v in reversed(last_values):
1201 try:
1202 return v + 1
1203 except TypeError:
1204 pass
1205 return start
1206
1207 @classmethod
1208 def _missing_(cls, value):
1209 return None
1210
1211 def __repr__(self):
1212 v_repr = self.__class__._value_repr_ or repr
1213 return "<%s.%s: %s>" % (self.__class__.__name__, self._name_, v_repr(self._value_))
1214
1215 def __str__(self):
1216 return "%s.%s" % (self.__class__.__name__, self._name_, )
1217
1218 def __dir__(self):
1219 """
1220 Returns all members and all public methods
1221 """
1222 if self.__class__._member_type_ is object:
1223 interesting = set(['__class__', '__doc__', '__eq__', '__hash__', '__module__', 'name', 'value'])
1224 else:
1225 interesting = set(object.__dir__(self))
1226 for name in getattr(self, '__dict__', []):
1227 if name[0] != '_':
1228 interesting.add(name)
1229 for cls in self.__class__.mro():
1230 for name, obj in cls.__dict__.items():
1231 if name[0] == '_':
1232 continue
1233 if isinstance(obj, property):
1234 # that's an enum.property
1235 if obj.fget is not None or name not in self._member_map_:
1236 interesting.add(name)
1237 else:
1238 # in case it was added by `dir(self)`
1239 interesting.discard(name)
1240 else:
1241 interesting.add(name)
1242 names = sorted(
1243 set(['__class__', '__doc__', '__eq__', '__hash__', '__module__'])
1244 | interesting
1245 )
1246 return names
1247
1248 def __format__(self, format_spec):
1249 return str.__format__(str(self), format_spec)
1250
1251 def __hash__(self):
1252 return hash(self._name_)
1253
1254 def __reduce_ex__(self, proto):
1255 return self.__class__, (self._value_, )
1256
1257 def __deepcopy__(self,memo):
1258 return self
1259
1260 def __copy__(self):
1261 return self
1262
1263 # enum.property is used to provide access to the `name` and
1264 # `value` attributes of enum members while keeping some measure of
1265 # protection from modification, while still allowing for an enumeration
1266 # to have members named `name` and `value`. This works because each
1267 # instance of enum.property saves its companion member, which it returns
1268 # on class lookup; on instance lookup it either executes a provided function
1269 # or raises an AttributeError.
1270
1271 @property
1272 def name(self):
1273 """The name of the Enum member."""
1274 return self._name_
1275
1276 @property
1277 def value(self):
1278 """The value of the Enum member."""
1279 return self._value_
1280
1281
1282 class ESC[4;38;5;81mReprEnum(ESC[4;38;5;149mEnum):
1283 """
1284 Only changes the repr(), leaving str() and format() to the mixed-in type.
1285 """
1286
1287
1288 class ESC[4;38;5;81mIntEnum(ESC[4;38;5;149mint, ESC[4;38;5;149mReprEnum):
1289 """
1290 Enum where members are also (and must be) ints
1291 """
1292
1293
1294 class ESC[4;38;5;81mStrEnum(ESC[4;38;5;149mstr, ESC[4;38;5;149mReprEnum):
1295 """
1296 Enum where members are also (and must be) strings
1297 """
1298
1299 def __new__(cls, *values):
1300 "values must already be of type `str`"
1301 if len(values) > 3:
1302 raise TypeError('too many arguments for str(): %r' % (values, ))
1303 if len(values) == 1:
1304 # it must be a string
1305 if not isinstance(values[0], str):
1306 raise TypeError('%r is not a string' % (values[0], ))
1307 if len(values) >= 2:
1308 # check that encoding argument is a string
1309 if not isinstance(values[1], str):
1310 raise TypeError('encoding must be a string, not %r' % (values[1], ))
1311 if len(values) == 3:
1312 # check that errors argument is a string
1313 if not isinstance(values[2], str):
1314 raise TypeError('errors must be a string, not %r' % (values[2]))
1315 value = str(*values)
1316 member = str.__new__(cls, value)
1317 member._value_ = value
1318 return member
1319
1320 @staticmethod
1321 def _generate_next_value_(name, start, count, last_values):
1322 """
1323 Return the lower-cased version of the member name.
1324 """
1325 return name.lower()
1326
1327
1328 def pickle_by_global_name(self, proto):
1329 # should not be used with Flag-type enums
1330 return self.name
1331 _reduce_ex_by_global_name = pickle_by_global_name
1332
1333 def pickle_by_enum_name(self, proto):
1334 # should not be used with Flag-type enums
1335 return getattr, (self.__class__, self._name_)
1336
1337 class ESC[4;38;5;81mFlagBoundary(ESC[4;38;5;149mStrEnum):
1338 """
1339 control how out of range values are handled
1340 "strict" -> error is raised [default for Flag]
1341 "conform" -> extra bits are discarded
1342 "eject" -> lose flag status
1343 "keep" -> keep flag status and all bits [default for IntFlag]
1344 """
1345 STRICT = auto()
1346 CONFORM = auto()
1347 EJECT = auto()
1348 KEEP = auto()
1349 STRICT, CONFORM, EJECT, KEEP = FlagBoundary
1350
1351
1352 class ESC[4;38;5;81mFlag(ESC[4;38;5;149mEnum, boundary=ESC[4;38;5;149mSTRICT):
1353 """
1354 Support for flags
1355 """
1356
1357 _numeric_repr_ = repr
1358
1359 @staticmethod
1360 def _generate_next_value_(name, start, count, last_values):
1361 """
1362 Generate the next value when not given.
1363
1364 name: the name of the member
1365 start: the initial start value or None
1366 count: the number of existing members
1367 last_values: the last value assigned or None
1368 """
1369 if not count:
1370 return start if start is not None else 1
1371 last_value = max(last_values)
1372 try:
1373 high_bit = _high_bit(last_value)
1374 except Exception:
1375 raise TypeError('invalid flag value %r' % last_value) from None
1376 return 2 ** (high_bit+1)
1377
1378 @classmethod
1379 def _iter_member_by_value_(cls, value):
1380 """
1381 Extract all members from the value in definition (i.e. increasing value) order.
1382 """
1383 for val in _iter_bits_lsb(value & cls._flag_mask_):
1384 yield cls._value2member_map_.get(val)
1385
1386 _iter_member_ = _iter_member_by_value_
1387
1388 @classmethod
1389 def _iter_member_by_def_(cls, value):
1390 """
1391 Extract all members from the value in definition order.
1392 """
1393 yield from sorted(
1394 cls._iter_member_by_value_(value),
1395 key=lambda m: m._sort_order_,
1396 )
1397
1398 @classmethod
1399 def _missing_(cls, value):
1400 """
1401 Create a composite member containing all canonical members present in `value`.
1402
1403 If non-member values are present, result depends on `_boundary_` setting.
1404 """
1405 if not isinstance(value, int):
1406 raise ValueError(
1407 "%r is not a valid %s" % (value, cls.__qualname__)
1408 )
1409 # check boundaries
1410 # - value must be in range (e.g. -16 <-> +15, i.e. ~15 <-> 15)
1411 # - value must not include any skipped flags (e.g. if bit 2 is not
1412 # defined, then 0d10 is invalid)
1413 flag_mask = cls._flag_mask_
1414 singles_mask = cls._singles_mask_
1415 all_bits = cls._all_bits_
1416 neg_value = None
1417 if (
1418 not ~all_bits <= value <= all_bits
1419 or value & (all_bits ^ flag_mask)
1420 ):
1421 if cls._boundary_ is STRICT:
1422 max_bits = max(value.bit_length(), flag_mask.bit_length())
1423 raise ValueError(
1424 "%r invalid value %r\n given %s\n allowed %s" % (
1425 cls, value, bin(value, max_bits), bin(flag_mask, max_bits),
1426 ))
1427 elif cls._boundary_ is CONFORM:
1428 value = value & flag_mask
1429 elif cls._boundary_ is EJECT:
1430 return value
1431 elif cls._boundary_ is KEEP:
1432 if value < 0:
1433 value = (
1434 max(all_bits+1, 2**(value.bit_length()))
1435 + value
1436 )
1437 else:
1438 raise ValueError(
1439 '%r unknown flag boundary %r' % (cls, cls._boundary_, )
1440 )
1441 if value < 0:
1442 neg_value = value
1443 value = all_bits + 1 + value
1444 # get members and unknown
1445 unknown = value & ~flag_mask
1446 aliases = value & ~singles_mask
1447 member_value = value & singles_mask
1448 if unknown and cls._boundary_ is not KEEP:
1449 raise ValueError(
1450 '%s(%r) --> unknown values %r [%s]'
1451 % (cls.__name__, value, unknown, bin(unknown))
1452 )
1453 # normal Flag?
1454 if cls._member_type_ is object:
1455 # construct a singleton enum pseudo-member
1456 pseudo_member = object.__new__(cls)
1457 else:
1458 pseudo_member = cls._member_type_.__new__(cls, value)
1459 if not hasattr(pseudo_member, '_value_'):
1460 pseudo_member._value_ = value
1461 if member_value or aliases:
1462 members = []
1463 combined_value = 0
1464 for m in cls._iter_member_(member_value):
1465 members.append(m)
1466 combined_value |= m._value_
1467 if aliases:
1468 value = member_value | aliases
1469 for n, pm in cls._member_map_.items():
1470 if pm not in members and pm._value_ and pm._value_ & value == pm._value_:
1471 members.append(pm)
1472 combined_value |= pm._value_
1473 unknown = value ^ combined_value
1474 pseudo_member._name_ = '|'.join([m._name_ for m in members])
1475 if not combined_value:
1476 pseudo_member._name_ = None
1477 elif unknown and cls._boundary_ is STRICT:
1478 raise ValueError('%r: no members with value %r' % (cls, unknown))
1479 elif unknown:
1480 pseudo_member._name_ += '|%s' % cls._numeric_repr_(unknown)
1481 else:
1482 pseudo_member._name_ = None
1483 # use setdefault in case another thread already created a composite
1484 # with this value
1485 # note: zero is a special case -- always add it
1486 pseudo_member = cls._value2member_map_.setdefault(value, pseudo_member)
1487 if neg_value is not None:
1488 cls._value2member_map_[neg_value] = pseudo_member
1489 return pseudo_member
1490
1491 def __contains__(self, other):
1492 """
1493 Returns True if self has at least the same flags set as other.
1494 """
1495 if not isinstance(other, self.__class__):
1496 raise TypeError(
1497 "unsupported operand type(s) for 'in': %r and %r" % (
1498 type(other).__qualname__, self.__class__.__qualname__))
1499 return other._value_ & self._value_ == other._value_
1500
1501 def __iter__(self):
1502 """
1503 Returns flags in definition order.
1504 """
1505 yield from self._iter_member_(self._value_)
1506
1507 def __len__(self):
1508 return self._value_.bit_count()
1509
1510 def __repr__(self):
1511 cls_name = self.__class__.__name__
1512 v_repr = self.__class__._value_repr_ or repr
1513 if self._name_ is None:
1514 return "<%s: %s>" % (cls_name, v_repr(self._value_))
1515 else:
1516 return "<%s.%s: %s>" % (cls_name, self._name_, v_repr(self._value_))
1517
1518 def __str__(self):
1519 cls_name = self.__class__.__name__
1520 if self._name_ is None:
1521 return '%s(%r)' % (cls_name, self._value_)
1522 else:
1523 return "%s.%s" % (cls_name, self._name_)
1524
1525 def __bool__(self):
1526 return bool(self._value_)
1527
1528 def __or__(self, other):
1529 if isinstance(other, self.__class__):
1530 other = other._value_
1531 elif self._member_type_ is not object and isinstance(other, self._member_type_):
1532 other = other
1533 else:
1534 return NotImplemented
1535 value = self._value_
1536 return self.__class__(value | other)
1537
1538 def __and__(self, other):
1539 if isinstance(other, self.__class__):
1540 other = other._value_
1541 elif self._member_type_ is not object and isinstance(other, self._member_type_):
1542 other = other
1543 else:
1544 return NotImplemented
1545 value = self._value_
1546 return self.__class__(value & other)
1547
1548 def __xor__(self, other):
1549 if isinstance(other, self.__class__):
1550 other = other._value_
1551 elif self._member_type_ is not object and isinstance(other, self._member_type_):
1552 other = other
1553 else:
1554 return NotImplemented
1555 value = self._value_
1556 return self.__class__(value ^ other)
1557
1558 def __invert__(self):
1559 if self._inverted_ is None:
1560 if self._boundary_ in (EJECT, KEEP):
1561 self._inverted_ = self.__class__(~self._value_)
1562 else:
1563 self._inverted_ = self.__class__(self._singles_mask_ & ~self._value_)
1564 return self._inverted_
1565
1566 __rand__ = __and__
1567 __ror__ = __or__
1568 __rxor__ = __xor__
1569
1570
1571 class ESC[4;38;5;81mIntFlag(ESC[4;38;5;149mint, ESC[4;38;5;149mReprEnum, ESC[4;38;5;149mFlag, boundary=ESC[4;38;5;149mKEEP):
1572 """
1573 Support for integer-based Flags
1574 """
1575
1576
1577 def _high_bit(value):
1578 """
1579 returns index of highest bit, or -1 if value is zero or negative
1580 """
1581 return value.bit_length() - 1
1582
1583 def unique(enumeration):
1584 """
1585 Class decorator for enumerations ensuring unique member values.
1586 """
1587 duplicates = []
1588 for name, member in enumeration.__members__.items():
1589 if name != member.name:
1590 duplicates.append((name, member.name))
1591 if duplicates:
1592 alias_details = ', '.join(
1593 ["%s -> %s" % (alias, name) for (alias, name) in duplicates])
1594 raise ValueError('duplicate values found in %r: %s' %
1595 (enumeration, alias_details))
1596 return enumeration
1597
1598 def _dataclass_repr(self):
1599 dcf = self.__dataclass_fields__
1600 return ', '.join(
1601 '%s=%r' % (k, getattr(self, k))
1602 for k in dcf.keys()
1603 if dcf[k].repr
1604 )
1605
1606 def global_enum_repr(self):
1607 """
1608 use module.enum_name instead of class.enum_name
1609
1610 the module is the last module in case of a multi-module name
1611 """
1612 module = self.__class__.__module__.split('.')[-1]
1613 return '%s.%s' % (module, self._name_)
1614
1615 def global_flag_repr(self):
1616 """
1617 use module.flag_name instead of class.flag_name
1618
1619 the module is the last module in case of a multi-module name
1620 """
1621 module = self.__class__.__module__.split('.')[-1]
1622 cls_name = self.__class__.__name__
1623 if self._name_ is None:
1624 return "%s.%s(%r)" % (module, cls_name, self._value_)
1625 if _is_single_bit(self):
1626 return '%s.%s' % (module, self._name_)
1627 if self._boundary_ is not FlagBoundary.KEEP:
1628 return '|'.join(['%s.%s' % (module, name) for name in self.name.split('|')])
1629 else:
1630 name = []
1631 for n in self._name_.split('|'):
1632 if n[0].isdigit():
1633 name.append(n)
1634 else:
1635 name.append('%s.%s' % (module, n))
1636 return '|'.join(name)
1637
1638 def global_str(self):
1639 """
1640 use enum_name instead of class.enum_name
1641 """
1642 if self._name_ is None:
1643 cls_name = self.__class__.__name__
1644 return "%s(%r)" % (cls_name, self._value_)
1645 else:
1646 return self._name_
1647
1648 def global_enum(cls, update_str=False):
1649 """
1650 decorator that makes the repr() of an enum member reference its module
1651 instead of its class; also exports all members to the enum's module's
1652 global namespace
1653 """
1654 if issubclass(cls, Flag):
1655 cls.__repr__ = global_flag_repr
1656 else:
1657 cls.__repr__ = global_enum_repr
1658 if not issubclass(cls, ReprEnum) or update_str:
1659 cls.__str__ = global_str
1660 sys.modules[cls.__module__].__dict__.update(cls.__members__)
1661 return cls
1662
1663 def _simple_enum(etype=Enum, *, boundary=None, use_args=None):
1664 """
1665 Class decorator that converts a normal class into an :class:`Enum`. No
1666 safety checks are done, and some advanced behavior (such as
1667 :func:`__init_subclass__`) is not available. Enum creation can be faster
1668 using :func:`simple_enum`.
1669
1670 >>> from enum import Enum, _simple_enum
1671 >>> @_simple_enum(Enum)
1672 ... class Color:
1673 ... RED = auto()
1674 ... GREEN = auto()
1675 ... BLUE = auto()
1676 >>> Color
1677 <enum 'Color'>
1678 """
1679 def convert_class(cls):
1680 nonlocal use_args
1681 cls_name = cls.__name__
1682 if use_args is None:
1683 use_args = etype._use_args_
1684 __new__ = cls.__dict__.get('__new__')
1685 if __new__ is not None:
1686 new_member = __new__.__func__
1687 else:
1688 new_member = etype._member_type_.__new__
1689 attrs = {}
1690 body = {}
1691 if __new__ is not None:
1692 body['__new_member__'] = new_member
1693 body['_new_member_'] = new_member
1694 body['_use_args_'] = use_args
1695 body['_generate_next_value_'] = gnv = etype._generate_next_value_
1696 body['_member_names_'] = member_names = []
1697 body['_member_map_'] = member_map = {}
1698 body['_value2member_map_'] = value2member_map = {}
1699 body['_unhashable_values_'] = []
1700 body['_member_type_'] = member_type = etype._member_type_
1701 body['_value_repr_'] = etype._value_repr_
1702 if issubclass(etype, Flag):
1703 body['_boundary_'] = boundary or etype._boundary_
1704 body['_flag_mask_'] = None
1705 body['_all_bits_'] = None
1706 body['_singles_mask_'] = None
1707 body['_inverted_'] = None
1708 body['__or__'] = Flag.__or__
1709 body['__xor__'] = Flag.__xor__
1710 body['__and__'] = Flag.__and__
1711 body['__ror__'] = Flag.__ror__
1712 body['__rxor__'] = Flag.__rxor__
1713 body['__rand__'] = Flag.__rand__
1714 body['__invert__'] = Flag.__invert__
1715 for name, obj in cls.__dict__.items():
1716 if name in ('__dict__', '__weakref__'):
1717 continue
1718 if _is_dunder(name) or _is_private(cls_name, name) or _is_sunder(name) or _is_descriptor(obj):
1719 body[name] = obj
1720 else:
1721 attrs[name] = obj
1722 if cls.__dict__.get('__doc__') is None:
1723 body['__doc__'] = 'An enumeration.'
1724 #
1725 # double check that repr and friends are not the mixin's or various
1726 # things break (such as pickle)
1727 # however, if the method is defined in the Enum itself, don't replace
1728 # it
1729 enum_class = type(cls_name, (etype, ), body, boundary=boundary, _simple=True)
1730 for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'):
1731 if name not in body:
1732 # check for mixin overrides before replacing
1733 enum_method = getattr(etype, name)
1734 found_method = getattr(enum_class, name)
1735 object_method = getattr(object, name)
1736 data_type_method = getattr(member_type, name)
1737 if found_method in (data_type_method, object_method):
1738 setattr(enum_class, name, enum_method)
1739 gnv_last_values = []
1740 if issubclass(enum_class, Flag):
1741 # Flag / IntFlag
1742 single_bits = multi_bits = 0
1743 for name, value in attrs.items():
1744 if isinstance(value, auto) and auto.value is _auto_null:
1745 value = gnv(name, 1, len(member_names), gnv_last_values)
1746 if value in value2member_map:
1747 # an alias to an existing member
1748 member = value2member_map[value]
1749 redirect = property()
1750 redirect.member = member
1751 redirect.__set_name__(enum_class, name)
1752 setattr(enum_class, name, redirect)
1753 member_map[name] = member
1754 else:
1755 # create the member
1756 if use_args:
1757 if not isinstance(value, tuple):
1758 value = (value, )
1759 member = new_member(enum_class, *value)
1760 value = value[0]
1761 else:
1762 member = new_member(enum_class)
1763 if __new__ is None:
1764 member._value_ = value
1765 member._name_ = name
1766 member.__objclass__ = enum_class
1767 member.__init__(value)
1768 redirect = property()
1769 redirect.member = member
1770 redirect.__set_name__(enum_class, name)
1771 setattr(enum_class, name, redirect)
1772 member_map[name] = member
1773 member._sort_order_ = len(member_names)
1774 value2member_map[value] = member
1775 if _is_single_bit(value):
1776 # not a multi-bit alias, record in _member_names_ and _flag_mask_
1777 member_names.append(name)
1778 single_bits |= value
1779 else:
1780 multi_bits |= value
1781 gnv_last_values.append(value)
1782 enum_class._flag_mask_ = single_bits | multi_bits
1783 enum_class._singles_mask_ = single_bits
1784 enum_class._all_bits_ = 2 ** ((single_bits|multi_bits).bit_length()) - 1
1785 # set correct __iter__
1786 member_list = [m._value_ for m in enum_class]
1787 if member_list != sorted(member_list):
1788 enum_class._iter_member_ = enum_class._iter_member_by_def_
1789 else:
1790 # Enum / IntEnum / StrEnum
1791 for name, value in attrs.items():
1792 if isinstance(value, auto):
1793 if value.value is _auto_null:
1794 value.value = gnv(name, 1, len(member_names), gnv_last_values)
1795 value = value.value
1796 if value in value2member_map:
1797 # an alias to an existing member
1798 member = value2member_map[value]
1799 redirect = property()
1800 redirect.member = member
1801 redirect.__set_name__(enum_class, name)
1802 setattr(enum_class, name, redirect)
1803 member_map[name] = member
1804 else:
1805 # create the member
1806 if use_args:
1807 if not isinstance(value, tuple):
1808 value = (value, )
1809 member = new_member(enum_class, *value)
1810 value = value[0]
1811 else:
1812 member = new_member(enum_class)
1813 if __new__ is None:
1814 member._value_ = value
1815 member._name_ = name
1816 member.__objclass__ = enum_class
1817 member.__init__(value)
1818 member._sort_order_ = len(member_names)
1819 redirect = property()
1820 redirect.member = member
1821 redirect.__set_name__(enum_class, name)
1822 setattr(enum_class, name, redirect)
1823 member_map[name] = member
1824 value2member_map[value] = member
1825 member_names.append(name)
1826 gnv_last_values.append(value)
1827 if '__new__' in body:
1828 enum_class.__new_member__ = enum_class.__new__
1829 enum_class.__new__ = Enum.__new__
1830 return enum_class
1831 return convert_class
1832
1833 @_simple_enum(StrEnum)
1834 class ESC[4;38;5;81mEnumCheck:
1835 """
1836 various conditions to check an enumeration for
1837 """
1838 CONTINUOUS = "no skipped integer values"
1839 NAMED_FLAGS = "multi-flag aliases may not contain unnamed flags"
1840 UNIQUE = "one name per value"
1841 CONTINUOUS, NAMED_FLAGS, UNIQUE = EnumCheck
1842
1843
1844 class ESC[4;38;5;81mverify:
1845 """
1846 Check an enumeration for various constraints. (see EnumCheck)
1847 """
1848 def __init__(self, *checks):
1849 self.checks = checks
1850 def __call__(self, enumeration):
1851 checks = self.checks
1852 cls_name = enumeration.__name__
1853 if Flag is not None and issubclass(enumeration, Flag):
1854 enum_type = 'flag'
1855 elif issubclass(enumeration, Enum):
1856 enum_type = 'enum'
1857 else:
1858 raise TypeError("the 'verify' decorator only works with Enum and Flag")
1859 for check in checks:
1860 if check is UNIQUE:
1861 # check for duplicate names
1862 duplicates = []
1863 for name, member in enumeration.__members__.items():
1864 if name != member.name:
1865 duplicates.append((name, member.name))
1866 if duplicates:
1867 alias_details = ', '.join(
1868 ["%s -> %s" % (alias, name) for (alias, name) in duplicates])
1869 raise ValueError('aliases found in %r: %s' %
1870 (enumeration, alias_details))
1871 elif check is CONTINUOUS:
1872 values = set(e.value for e in enumeration)
1873 if len(values) < 2:
1874 continue
1875 low, high = min(values), max(values)
1876 missing = []
1877 if enum_type == 'flag':
1878 # check for powers of two
1879 for i in range(_high_bit(low)+1, _high_bit(high)):
1880 if 2**i not in values:
1881 missing.append(2**i)
1882 elif enum_type == 'enum':
1883 # check for powers of one
1884 for i in range(low+1, high):
1885 if i not in values:
1886 missing.append(i)
1887 else:
1888 raise Exception('verify: unknown type %r' % enum_type)
1889 if missing:
1890 raise ValueError(('invalid %s %r: missing values %s' % (
1891 enum_type, cls_name, ', '.join((str(m) for m in missing)))
1892 )[:256])
1893 # limit max length to protect against DOS attacks
1894 elif check is NAMED_FLAGS:
1895 # examine each alias and check for unnamed flags
1896 member_names = enumeration._member_names_
1897 member_values = [m.value for m in enumeration]
1898 missing_names = []
1899 missing_value = 0
1900 for name, alias in enumeration._member_map_.items():
1901 if name in member_names:
1902 # not an alias
1903 continue
1904 if alias.value < 0:
1905 # negative numbers are not checked
1906 continue
1907 values = list(_iter_bits_lsb(alias.value))
1908 missed = [v for v in values if v not in member_values]
1909 if missed:
1910 missing_names.append(name)
1911 missing_value |= reduce(_or_, missed)
1912 if missing_names:
1913 if len(missing_names) == 1:
1914 alias = 'alias %s is missing' % missing_names[0]
1915 else:
1916 alias = 'aliases %s and %s are missing' % (
1917 ', '.join(missing_names[:-1]), missing_names[-1]
1918 )
1919 if _is_single_bit(missing_value):
1920 value = 'value 0x%x' % missing_value
1921 else:
1922 value = 'combined values of 0x%x' % missing_value
1923 raise ValueError(
1924 'invalid Flag %r: %s %s [use enum.show_flag_values(value) for details]'
1925 % (cls_name, alias, value)
1926 )
1927 return enumeration
1928
1929 def _test_simple_enum(checked_enum, simple_enum):
1930 """
1931 A function that can be used to test an enum created with :func:`_simple_enum`
1932 against the version created by subclassing :class:`Enum`::
1933
1934 >>> from enum import Enum, _simple_enum, _test_simple_enum
1935 >>> @_simple_enum(Enum)
1936 ... class Color:
1937 ... RED = auto()
1938 ... GREEN = auto()
1939 ... BLUE = auto()
1940 >>> class CheckedColor(Enum):
1941 ... RED = auto()
1942 ... GREEN = auto()
1943 ... BLUE = auto()
1944 >>> _test_simple_enum(CheckedColor, Color)
1945
1946 If differences are found, a :exc:`TypeError` is raised.
1947 """
1948 failed = []
1949 if checked_enum.__dict__ != simple_enum.__dict__:
1950 checked_dict = checked_enum.__dict__
1951 checked_keys = list(checked_dict.keys())
1952 simple_dict = simple_enum.__dict__
1953 simple_keys = list(simple_dict.keys())
1954 member_names = set(
1955 list(checked_enum._member_map_.keys())
1956 + list(simple_enum._member_map_.keys())
1957 )
1958 for key in set(checked_keys + simple_keys):
1959 if key in ('__module__', '_member_map_', '_value2member_map_', '__doc__'):
1960 # keys known to be different, or very long
1961 continue
1962 elif key in member_names:
1963 # members are checked below
1964 continue
1965 elif key not in simple_keys:
1966 failed.append("missing key: %r" % (key, ))
1967 elif key not in checked_keys:
1968 failed.append("extra key: %r" % (key, ))
1969 else:
1970 checked_value = checked_dict[key]
1971 simple_value = simple_dict[key]
1972 if callable(checked_value) or isinstance(checked_value, bltns.property):
1973 continue
1974 if key == '__doc__':
1975 # remove all spaces/tabs
1976 compressed_checked_value = checked_value.replace(' ','').replace('\t','')
1977 compressed_simple_value = simple_value.replace(' ','').replace('\t','')
1978 if compressed_checked_value != compressed_simple_value:
1979 failed.append("%r:\n %s\n %s" % (
1980 key,
1981 "checked -> %r" % (checked_value, ),
1982 "simple -> %r" % (simple_value, ),
1983 ))
1984 elif checked_value != simple_value:
1985 failed.append("%r:\n %s\n %s" % (
1986 key,
1987 "checked -> %r" % (checked_value, ),
1988 "simple -> %r" % (simple_value, ),
1989 ))
1990 failed.sort()
1991 for name in member_names:
1992 failed_member = []
1993 if name not in simple_keys:
1994 failed.append('missing member from simple enum: %r' % name)
1995 elif name not in checked_keys:
1996 failed.append('extra member in simple enum: %r' % name)
1997 else:
1998 checked_member_dict = checked_enum[name].__dict__
1999 checked_member_keys = list(checked_member_dict.keys())
2000 simple_member_dict = simple_enum[name].__dict__
2001 simple_member_keys = list(simple_member_dict.keys())
2002 for key in set(checked_member_keys + simple_member_keys):
2003 if key in ('__module__', '__objclass__', '_inverted_'):
2004 # keys known to be different or absent
2005 continue
2006 elif key not in simple_member_keys:
2007 failed_member.append("missing key %r not in the simple enum member %r" % (key, name))
2008 elif key not in checked_member_keys:
2009 failed_member.append("extra key %r in simple enum member %r" % (key, name))
2010 else:
2011 checked_value = checked_member_dict[key]
2012 simple_value = simple_member_dict[key]
2013 if checked_value != simple_value:
2014 failed_member.append("%r:\n %s\n %s" % (
2015 key,
2016 "checked member -> %r" % (checked_value, ),
2017 "simple member -> %r" % (simple_value, ),
2018 ))
2019 if failed_member:
2020 failed.append('%r member mismatch:\n %s' % (
2021 name, '\n '.join(failed_member),
2022 ))
2023 for method in (
2024 '__str__', '__repr__', '__reduce_ex__', '__format__',
2025 '__getnewargs_ex__', '__getnewargs__', '__reduce_ex__', '__reduce__'
2026 ):
2027 if method in simple_keys and method in checked_keys:
2028 # cannot compare functions, and it exists in both, so we're good
2029 continue
2030 elif method not in simple_keys and method not in checked_keys:
2031 # method is inherited -- check it out
2032 checked_method = getattr(checked_enum, method, None)
2033 simple_method = getattr(simple_enum, method, None)
2034 if hasattr(checked_method, '__func__'):
2035 checked_method = checked_method.__func__
2036 simple_method = simple_method.__func__
2037 if checked_method != simple_method:
2038 failed.append("%r: %-30s %s" % (
2039 method,
2040 "checked -> %r" % (checked_method, ),
2041 "simple -> %r" % (simple_method, ),
2042 ))
2043 else:
2044 # if the method existed in only one of the enums, it will have been caught
2045 # in the first checks above
2046 pass
2047 if failed:
2048 raise TypeError('enum mismatch:\n %s' % '\n '.join(failed))
2049
2050 def _old_convert_(etype, name, module, filter, source=None, *, boundary=None):
2051 """
2052 Create a new Enum subclass that replaces a collection of global constants
2053 """
2054 # convert all constants from source (or module) that pass filter() to
2055 # a new Enum called name, and export the enum and its members back to
2056 # module;
2057 # also, replace the __reduce_ex__ method so unpickling works in
2058 # previous Python versions
2059 module_globals = sys.modules[module].__dict__
2060 if source:
2061 source = source.__dict__
2062 else:
2063 source = module_globals
2064 # _value2member_map_ is populated in the same order every time
2065 # for a consistent reverse mapping of number to name when there
2066 # are multiple names for the same number.
2067 members = [
2068 (name, value)
2069 for name, value in source.items()
2070 if filter(name)]
2071 try:
2072 # sort by value
2073 members.sort(key=lambda t: (t[1], t[0]))
2074 except TypeError:
2075 # unless some values aren't comparable, in which case sort by name
2076 members.sort(key=lambda t: t[0])
2077 cls = etype(name, members, module=module, boundary=boundary or KEEP)
2078 return cls
2079
2080 _stdlib_enums = IntEnum, StrEnum, IntFlag