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