comparison env/lib/python3.7/site-packages/aenum/__init__.py @ 0:26e78fe6e8c4 draft

"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author shellac
date Sat, 02 May 2020 07:14:21 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:26e78fe6e8c4
1 """Python Advanced Enumerations & NameTuples"""
2
3 import sys as _sys
4 pyver = float('%s.%s' % _sys.version_info[:2])
5
6 import re
7
8 try:
9 from collections import OrderedDict
10 except ImportError:
11 OrderedDict = dict
12 from collections import defaultdict
13 try:
14 import sqlite3
15 except ImportError:
16 sqlite3 = None
17
18 if pyver >= 3:
19 from functools import reduce
20
21 from operator import or_ as _or_, and_ as _and_, xor as _xor_, inv as _inv_
22 from operator import abs as _abs_, add as _add_, floordiv as _floordiv_
23 from operator import lshift as _lshift_, rshift as _rshift_, mod as _mod_
24 from operator import mul as _mul_, neg as _neg_, pos as _pos_, pow as _pow_
25 from operator import truediv as _truediv_, sub as _sub_
26 if pyver < 3:
27 from operator import div as _div_
28
29 if pyver >= 3:
30 from inspect import getfullargspec
31 def getargspec(method):
32 args, varargs, keywords, defaults, _, _, _ = getfullargspec(method)
33 return args, varargs, keywords, defaults
34 else:
35 from inspect import getargspec
36
37
38 __all__ = [
39 'NamedConstant', 'constant', 'skip', 'nonmember', 'member', 'no_arg',
40 'Enum', 'IntEnum', 'AutoNumberEnum', 'OrderedEnum', 'UniqueEnum',
41 'Flag', 'IntFlag',
42 'AutoNumber', 'MultiValue', 'NoAlias', 'Unique',
43 'enum', 'extend_enum', 'unique', 'enum_property',
44 'NamedTuple', 'SqliteEnum',
45 ]
46 if sqlite3 is None:
47 __all__.remove('SqliteEnum')
48
49 version = 2, 2, 3
50
51 try:
52 any
53 except NameError:
54 def any(iterable):
55 for element in iterable:
56 if element:
57 return True
58 return False
59
60 try:
61 basestring
62 except NameError:
63 # In Python 2 basestring is the ancestor of both str and unicode
64 # in Python 3 it's just str, but was missing in 3.1
65 basestring = str
66
67 try:
68 unicode
69 except NameError:
70 # In Python 3 unicode no longer exists (it's just str)
71 unicode = str
72
73 try:
74 long
75 baseinteger = int, long
76 except NameError:
77 baseinteger = int
78 # deprecated
79 baseint = baseinteger
80
81 try:
82 NoneType
83 except NameError:
84 NoneType = type(None)
85
86 try:
87 # derive from stdlib enum if possible
88 import enum
89 if hasattr(enum, 'version'):
90 StdlibEnumMeta = StdlibEnum = None
91 else:
92 from enum import EnumMeta as StdlibEnumMeta, Enum as StdlibEnum
93 del enum
94 except ImportError:
95 StdlibEnumMeta = StdlibEnum = None
96
97 # will be exported later
98 AutoValue = AutoNumber = MultiValue = NoAlias = Unique = None
99
100 class enum_property(object):
101 """
102 This is a descriptor, used to define attributes that act differently
103 when accessed through an enum member and through an enum class.
104 Instance access is the same as property(), but access to an attribute
105 through the enum class will look in the class' _member_map_.
106 """
107
108 name = None # set by metaclass
109
110 def __init__(self, fget=None, doc=None):
111 self.fget = fget
112 self.__doc__ = doc or fget.__doc__
113
114 def __call__(self, func, doc=None):
115 self.fget = func
116 self.__doc__ = self.__doc__ or doc or func.__doc__
117
118 def __get__(self, instance, ownerclass=None):
119 if instance is None:
120 try:
121 return ownerclass._member_map_[self.name]
122 except KeyError:
123 raise AttributeError(self.name)
124 else:
125 return self.fget(instance)
126
127 def __set__(self, instance, value):
128 raise AttributeError("can't set attribute %r" % (self.name, ))
129
130 def __delete__(self, instance):
131 raise AttributeError("can't delete attribute %r" % (self.name, ))
132
133 _RouteClassAttributeToGetattr = enum_property
134
135 class NonMember(object):
136 """
137 Protects item from becaming an Enum member during class creation.
138 """
139 def __init__(self, value):
140 self.value = value
141
142 def __get__(self, instance, ownerclass=None):
143 return self.value
144 skip = nonmember = NonMember
145
146 class Member(object):
147 """
148 Forces item to became an Enum member during class creation.
149 """
150 def __init__(self, value):
151 self.value = value
152 member = Member
153
154
155 def _is_descriptor(obj):
156 """Returns True if obj is a descriptor, False otherwise."""
157 return (
158 hasattr(obj, '__get__') or
159 hasattr(obj, '__set__') or
160 hasattr(obj, '__delete__'))
161
162
163 def _is_dunder(name):
164 """Returns True if a __dunder__ name, False otherwise."""
165 return (len(name) > 4 and
166 name[:2] == name[-2:] == '__' and
167 name[2] != '_' and
168 name[-3] != '_')
169
170
171 def _is_sunder(name):
172 """Returns True if a _sunder_ name, False otherwise."""
173 return (len(name) > 2 and
174 name[0] == name[-1] == '_' and
175 name[1] != '_' and
176 name[-2] != '_')
177
178 def _is_internal_class(cls_name, obj):
179 # only 3.3 and up, always return False in 3.2 and below
180 if pyver < 3.3:
181 return False
182 else:
183 qualname = getattr(obj, '__qualname__', False)
184 return not _is_descriptor(obj) and qualname and re.search(r"\.?%s\.\w+$" % cls_name, qualname)
185
186 def _make_class_unpicklable(cls):
187 """Make the given class un-picklable."""
188 def _break_on_call_reduce(self, protocol=None):
189 raise TypeError('%r cannot be pickled' % (self, ))
190 cls.__reduce_ex__ = _break_on_call_reduce
191 cls.__module__ = '<unknown>'
192
193 def _check_auto_args(method):
194 """check if new generate method supports *args and **kwds"""
195 if isinstance(method, staticmethod):
196 method = method.__get__(type)
197 method = getattr(method, 'im_func', method)
198 args, varargs, keywords, defaults = getargspec(method)
199 return varargs is not None and keywords is not None
200
201 def _get_attr_from_chain(cls, attr):
202 sentinel = object()
203 for basecls in cls.mro():
204 obj = basecls.__dict__.get(attr, sentinel)
205 if obj is not sentinel:
206 return obj
207
208 def _value(obj):
209 if isinstance(obj, (auto, constant)):
210 return obj.value
211 else:
212 return obj
213
214 ################
215 # Constant stuff
216 ################
217
218 # metaclass and class dict for NamedConstant
219
220 class constant(object):
221 '''
222 Simple constant descriptor for NamedConstant and Enum use.
223 '''
224 def __init__(self, value, doc=None):
225 self.value = value
226 self.__doc__ = doc
227
228 def __get__(self, *args):
229 return self.value
230
231 def __repr__(self):
232 return '%s(%r)' % (self.__class__.__name__, self.value)
233
234 def __and__(self, other):
235 return _and_(self.value, _value(other))
236
237 def __rand__(self, other):
238 return _and_(_value(other), self.value)
239
240 def __invert__(self):
241 return _inv_(self.value)
242
243 def __or__(self, other):
244 return _or_(self.value, _value(other))
245
246 def __ror__(self, other):
247 return _or_(_value(other), self.value)
248
249 def __xor__(self, other):
250 return _xor_(self.value, _value(other))
251
252 def __rxor__(self, other):
253 return _xor_(_value(other), self.value)
254
255 def __abs__(self):
256 return _abs_(self.value)
257
258 def __add__(self, other):
259 return _add_(self.value, _value(other))
260
261 def __radd__(self, other):
262 return _add_(_value(other), self.value)
263
264 def __neg__(self):
265 return _neg_(self.value)
266
267 def __pos__(self):
268 return _pos_(self.value)
269
270 if pyver < 3:
271 def __div__(self, other):
272 return _div_(self.value, _value(other))
273
274 def __rdiv__(self, other):
275 return _div_(_value(other), (self.value))
276
277 def __floordiv__(self, other):
278 return _floordiv_(self.value, _value(other))
279
280 def __rfloordiv__(self, other):
281 return _floordiv_(_value(other), self.value)
282
283 def __truediv__(self, other):
284 return _truediv_(self.value, _value(other))
285
286 def __rtruediv__(self, other):
287 return _truediv_(_value(other), self.value)
288
289 def __lshift__(self, other):
290 return _lshift_(self.value, _value(other))
291
292 def __rlshift__(self, other):
293 return _lshift_(_value(other), self.value)
294
295 def __rshift__(self, other):
296 return _rshift_(self.value, _value(other))
297
298 def __rrshift__(self, other):
299 return _rshift_(_value(other), self.value)
300
301 def __mod__(self, other):
302 return _mod_(self.value, _value(other))
303
304 def __rmod__(self, other):
305 return _mod_(_value(other), self.value)
306
307 def __mul__(self, other):
308 return _mul_(self.value, _value(other))
309
310 def __rmul__(self, other):
311 return _mul_(_value(other), self.value)
312
313 def __pow__(self, other):
314 return _pow_(self.value, _value(other))
315
316 def __rpow__(self, other):
317 return _pow_(_value(other), self.value)
318
319 def __sub__(self, other):
320 return _sub_(self.value, _value(other))
321
322 def __rsub__(self, other):
323 return _sub_(_value(other), self.value)
324
325
326
327 NamedConstant = None
328
329 class _NamedConstantDict(dict):
330 """Track constant order and ensure names are not reused.
331
332 NamedConstantMeta will use the names found in self._names as the
333 Constant names.
334 """
335 def __init__(self):
336 super(_NamedConstantDict, self).__init__()
337 self._names = []
338
339 def __setitem__(self, key, value):
340 """Changes anything not dundered or not a constant descriptor.
341
342 If an constant name is used twice, an error is raised; duplicate
343 values are not checked for.
344
345 Single underscore (sunder) names are reserved.
346 """
347 if _is_sunder(key):
348 raise ValueError('_names_ are reserved for future NamedConstant use')
349 elif _is_dunder(key):
350 pass
351 elif key in self._names:
352 # overwriting an existing constant?
353 raise TypeError('attempt to reuse name: %r' % (key, ))
354 elif isinstance(value, constant) or not _is_descriptor(value):
355 if key in self:
356 # overwriting a descriptor?
357 raise TypeError('%s already defined as: %r' % (key, self[key]))
358 self._names.append(key)
359 super(_NamedConstantDict, self).__setitem__(key, value)
360
361
362 class NamedConstantMeta(type):
363 """
364 Block attempts to reassign NamedConstant attributes.
365 """
366
367 def __new__(metacls, cls, bases, clsdict):
368 if type(clsdict) is dict:
369 original_dict = clsdict
370 clsdict = _NamedConstantDict()
371 for k, v in original_dict.items():
372 clsdict[k] = v
373 newdict = {}
374 constants = {}
375 for name, obj in clsdict.items():
376 if name in clsdict._names:
377 constants[name] = obj
378 continue
379 elif isinstance(obj, nonmember):
380 obj = obj.value
381 newdict[name] = obj
382 newcls = super(NamedConstantMeta, metacls).__new__(metacls, cls, bases, newdict)
383 newcls._named_constant_cache_ = {}
384 for name, obj in constants.items():
385 newcls.__new__(newcls, name, obj)
386 return newcls
387
388 def __delattr__(cls, attr):
389 cur_obj = cls.__dict__.get(attr)
390 if NamedConstant is not None and isinstance(cur_obj, NamedConstant):
391 raise AttributeError('cannot delete constant <%s.%s>' % (cur_obj.__class__.__name__, cur_obj._name_))
392 super(NamedConstantMeta, cls).__delattr__(attr)
393
394 def __setattr__(cls, name, value):
395 """Block attempts to reassign NamedConstants.
396 """
397 cur_obj = cls.__dict__.get(name)
398 if NamedConstant is not None and isinstance(cur_obj, NamedConstant):
399 raise AttributeError('cannot rebind constant <%s.%s>' % (cur_obj.__class__.__name__, cur_obj._name_))
400 super(NamedConstantMeta, cls).__setattr__(name, value)
401
402 temp_constant_dict = {}
403 temp_constant_dict['__doc__'] = "NamedConstants protection.\n\n Derive from this class to lock NamedConstants.\n\n"
404
405 def __new__(cls, name, value, doc=None):
406 cur_obj = cls.__dict__.get(name)
407 if isinstance(cur_obj, NamedConstant):
408 raise AttributeError('cannot rebind constant <%s.%s>' % (cur_obj.__class__.__name__, cur_obj._name_))
409 elif isinstance(value, constant):
410 doc = doc or value.__doc__
411 value = value.value
412 metacls = cls.__class__
413 actual_type = type(value)
414 value_type = cls._named_constant_cache_.get(actual_type)
415 if value_type is None:
416 value_type = type(cls.__name__, (NamedConstant, type(value)), {})
417 cls._named_constant_cache_[type(value)] = value_type
418 obj = actual_type.__new__(value_type, value)
419 obj._name_ = name
420 obj._value_ = value
421 obj.__doc__ = doc
422 metacls.__setattr__(cls, name, obj)
423 return obj
424 temp_constant_dict['__new__'] = __new__
425 del __new__
426
427 def __repr__(self):
428 return "<%s.%s: %r>" % (
429 self.__class__.__name__, self._name_, self._value_)
430 temp_constant_dict['__repr__'] = __repr__
431 del __repr__
432
433 NamedConstant = NamedConstantMeta('NamedConstant', (object, ), temp_constant_dict)
434 Constant = NamedConstant
435 del temp_constant_dict
436
437 # now for a NamedTuple
438
439 class _NamedTupleDict(OrderedDict):
440 """Track field order and ensure field names are not reused.
441
442 NamedTupleMeta will use the names found in self._field_names to translate
443 to indices.
444 """
445 def __init__(self, *args, **kwds):
446 self._field_names = []
447 super(_NamedTupleDict, self).__init__(*args, **kwds)
448
449 def __setitem__(self, key, value):
450 """Records anything not dundered or not a descriptor.
451
452 If a field name is used twice, an error is raised.
453
454 Single underscore (sunder) names are reserved.
455 """
456 if _is_sunder(key):
457 if key not in ('_size_', '_order_'):
458 raise ValueError('_names_ are reserved for future NamedTuple use')
459 elif _is_dunder(key):
460 if key == '__order__':
461 key = '_order_'
462 elif key in self._field_names:
463 # overwriting a field?
464 raise TypeError('attempt to reuse field name: %r' % (key, ))
465 elif not _is_descriptor(value):
466 if key in self:
467 # field overwriting a descriptor?
468 raise TypeError('%s already defined as: %r' % (key, self[key]))
469 self._field_names.append(key)
470 super(_NamedTupleDict, self).__setitem__(key, value)
471
472
473 class _TupleAttributeAtIndex(object):
474
475 def __init__(self, name, index, doc, default):
476 self.name = name
477 self.index = index
478 if doc is undefined:
479 doc = None
480 self.__doc__ = doc
481 self.default = default
482
483 def __get__(self, instance, owner):
484 if instance is None:
485 return self
486 if len(instance) <= self.index:
487 raise AttributeError('%s instance has no value for %s' % (instance.__class__.__name__, self.name))
488 return instance[self.index]
489
490 def __repr__(self):
491 return '%s(%d)' % (self.__class__.__name__, self.index)
492
493
494 class undefined(object):
495 def __repr__(self):
496 return 'undefined'
497 def __bool__(self):
498 return False
499 __nonzero__ = __bool__
500 undefined = undefined()
501
502
503 class TupleSize(NamedConstant):
504 fixed = constant('fixed', 'tuple length is static')
505 minimum = constant('minimum', 'tuple must be at least x long (x is calculated during creation')
506 variable = constant('variable', 'tuple length can be anything')
507
508 class NamedTupleMeta(type):
509 """Metaclass for NamedTuple"""
510
511 @classmethod
512 def __prepare__(metacls, cls, bases, size=undefined):
513 return _NamedTupleDict()
514
515 def __init__(cls, *args , **kwds):
516 super(NamedTupleMeta, cls).__init__(*args)
517
518 def __new__(metacls, cls, bases, clsdict, size=undefined):
519 if bases == (object, ):
520 bases = (tuple, object)
521 elif tuple not in bases:
522 if object in bases:
523 index = bases.index(object)
524 bases = bases[:index] + (tuple, ) + bases[index:]
525 else:
526 bases = bases + (tuple, )
527 # include any fields from base classes
528 base_dict = _NamedTupleDict()
529 namedtuple_bases = []
530 for base in bases:
531 if isinstance(base, NamedTupleMeta):
532 namedtuple_bases.append(base)
533 i = 0
534 if namedtuple_bases:
535 for name, index, doc, default in metacls._convert_fields(*namedtuple_bases):
536 base_dict[name] = index, doc, default
537 i = max(i, index)
538 # construct properly ordered dict with normalized indexes
539 for k, v in clsdict.items():
540 base_dict[k] = v
541 original_dict = base_dict
542 if size is not undefined and '_size_' in original_dict:
543 raise TypeError('_size_ cannot be set if "size" is passed in header')
544 add_order = isinstance(clsdict, _NamedTupleDict)
545 clsdict = _NamedTupleDict()
546 clsdict.setdefault('_size_', size or TupleSize.fixed)
547 unnumbered = OrderedDict()
548 numbered = OrderedDict()
549 _order_ = original_dict.pop('_order_', [])
550 if _order_ :
551 _order_ = _order_.replace(',',' ').split()
552 add_order = False
553 # and process this class
554 for k, v in original_dict.items():
555 if k not in original_dict._field_names:
556 clsdict[k] = v
557 else:
558 # TODO:normalize v here
559 if isinstance(v, baseinteger):
560 # assume an offset
561 v = v, undefined, undefined
562 i = v[0] + 1
563 target = numbered
564 elif isinstance(v, basestring):
565 # assume a docstring
566 if add_order:
567 v = i, v, undefined
568 i += 1
569 target = numbered
570 else:
571 v = undefined, v, undefined
572 target = unnumbered
573 elif isinstance(v, tuple) and len(v) in (2, 3) and isinstance(v[0], baseinteger) and isinstance(v[1], (basestring, NoneType)):
574 # assume an offset, a docstring, and (maybe) a default
575 if len(v) == 2:
576 v = v + (undefined, )
577 v = v
578 i = v[0] + 1
579 target = numbered
580 elif isinstance(v, tuple) and len(v) in (1, 2) and isinstance(v[0], (basestring, NoneType)):
581 # assume a docstring, and (maybe) a default
582 if len(v) == 1:
583 v = v + (undefined, )
584 if add_order:
585 v = (i, ) + v
586 i += 1
587 target = numbered
588 else:
589 v = (undefined, ) + v
590 target = unnumbered
591 else:
592 # refuse to guess further
593 raise ValueError('not sure what to do with %s=%r (should be OFFSET [, DOC [, DEFAULT]])' % (k, v))
594 target[k] = v
595 # all index values have been normalized
596 # deal with _order_ (or lack thereof)
597 fields = []
598 aliases = []
599 seen = set()
600 max_len = 0
601 if not _order_:
602 if unnumbered:
603 raise ValueError("_order_ not specified and OFFSETs not declared for %r" % (unnumbered.keys(), ))
604 for name, (index, doc, default) in sorted(numbered.items(), key=lambda nv: (nv[1][0], nv[0])):
605 if index in seen:
606 aliases.append(name)
607 else:
608 fields.append(name)
609 seen.add(index)
610 max_len = max(max_len, index + 1)
611 offsets = numbered
612 else:
613 # check if any unnumbered not in _order_
614 missing = set(unnumbered) - set(_order_)
615 if missing:
616 raise ValueError("unable to order fields: %s (use _order_ or specify OFFSET" % missing)
617 offsets = OrderedDict()
618 # if any unnumbered, number them from their position in _order_
619 i = 0
620 for k in _order_:
621 try:
622 index, doc, default = unnumbered.pop(k, None) or numbered.pop(k)
623 except IndexError:
624 raise ValueError('%s (from _order_) not found in %s' % (k, cls))
625 if index is not undefined:
626 i = index
627 if i in seen:
628 aliases.append(k)
629 else:
630 fields.append(k)
631 seen.add(i)
632 offsets[k] = i, doc, default
633 i += 1
634 max_len = max(max_len, i)
635 # now handle anything in numbered
636 for k, (index, doc, default) in sorted(numbered.items(), key=lambda nv: (nv[1][0], nv[0])):
637 if index in seen:
638 aliases.append(k)
639 else:
640 fields.append(k)
641 seen.add(index)
642 offsets[k] = index, doc, default
643 max_len = max(max_len, index+1)
644
645 # at this point fields and aliases should be ordered lists, offsets should be an
646 # OrdededDict with each value an int, str or None or undefined, default or None or undefined
647 assert len(fields) + len(aliases) == len(offsets), "number of fields + aliases != number of offsets"
648 assert set(fields) & set(offsets) == set(fields), "some fields are not in offsets: %s" % set(fields) & set(offsets)
649 assert set(aliases) & set(offsets) == set(aliases), "some aliases are not in offsets: %s" % set(aliases) & set(offsets)
650 for name, (index, doc, default) in offsets.items():
651 assert isinstance(index, baseinteger), "index for %s is not an int (%s:%r)" % (name, type(index), index)
652 assert isinstance(doc, (basestring, NoneType)) or doc is undefined, "doc is not a str, None, nor undefined (%s:%r)" % (name, type(doc), doc)
653
654 # create descriptors for fields
655 for name, (index, doc, default) in offsets.items():
656 clsdict[name] = _TupleAttributeAtIndex(name, index, doc, default)
657 clsdict['__slots__'] = ()
658
659 # create our new NamedTuple type
660 namedtuple_class = super(NamedTupleMeta, metacls).__new__(metacls, cls, bases, clsdict)
661 namedtuple_class._fields_ = fields
662 namedtuple_class._aliases_ = aliases
663 namedtuple_class._defined_len_ = max_len
664 return namedtuple_class
665
666 @staticmethod
667 def _convert_fields(*namedtuples):
668 "create list of index, doc, default triplets for cls in namedtuples"
669 all_fields = []
670 for cls in namedtuples:
671 base = len(all_fields)
672 for field in cls._fields_:
673 desc = getattr(cls, field)
674 all_fields.append((field, base+desc.index, desc.__doc__, desc.default))
675 return all_fields
676
677 def __add__(cls, other):
678 "A new NamedTuple is created by concatenating the _fields_ and adjusting the descriptors"
679 if not isinstance(other, NamedTupleMeta):
680 return NotImplemented
681 return NamedTupleMeta('%s%s' % (cls.__name__, other.__name__), (cls, other), {})
682
683 def __call__(cls, *args, **kwds):
684 """Creates a new NamedTuple class or an instance of a NamedTuple subclass.
685
686 NamedTuple should have args of (class_name, names, module)
687
688 `names` can be:
689
690 * A string containing member names, separated either with spaces or
691 commas. Values are auto-numbered from 1.
692 * An iterable of member names. Values are auto-numbered from 1.
693 * An iterable of (member name, value) pairs.
694 * A mapping of member name -> value.
695
696 `module`, if set, will be stored in the new class' __module__ attribute;
697
698 Note: if `module` is not set this routine will attempt to discover the
699 calling module by walking the frame stack; if this is unsuccessful
700 the resulting class will not be pickleable.
701
702 subclass should have whatever arguments and/or keywords will be used to create an
703 instance of the subclass
704 """
705 if cls is NamedTuple:
706 original_args = args
707 original_kwds = kwds.copy()
708 # create a new subclass
709 try:
710 if 'class_name' in kwds:
711 class_name = kwds.pop('class_name')
712 else:
713 class_name, args = args[0], args[1:]
714 if 'names' in kwds:
715 names = kwds.pop('names')
716 else:
717 names, args = args[0], args[1:]
718 if 'module' in kwds:
719 module = kwds.pop('module')
720 elif args:
721 module, args = args[0], args[1:]
722 else:
723 module = None
724 if 'type' in kwds:
725 type = kwds.pop('type')
726 elif args:
727 type, args = args[0], args[1:]
728 else:
729 type = None
730
731 except IndexError:
732 raise TypeError('too few arguments to NamedTuple: %s, %s' % (original_args, original_kwds))
733 if args or kwds:
734 raise TypeError('too many arguments to NamedTuple: %s, %s' % (original_args, original_kwds))
735 if pyver < 3.0:
736 # if class_name is unicode, attempt a conversion to ASCII
737 if isinstance(class_name, unicode):
738 try:
739 class_name = class_name.encode('ascii')
740 except UnicodeEncodeError:
741 raise TypeError('%r is not representable in ASCII' % (class_name, ))
742 # quick exit if names is a NamedTuple
743 if isinstance(names, NamedTupleMeta):
744 names.__name__ = class_name
745 if type is not None and type not in names.__bases__:
746 names.__bases__ = (type, ) + names.__bases__
747 return names
748
749 metacls = cls.__class__
750 bases = (cls, )
751 clsdict = metacls.__prepare__(class_name, bases)
752
753 # special processing needed for names?
754 if isinstance(names, basestring):
755 names = names.replace(',', ' ').split()
756 if isinstance(names, (tuple, list)) and isinstance(names[0], basestring):
757 names = [(e, i) for (i, e) in enumerate(names)]
758 # Here, names is either an iterable of (name, index) or (name, index, doc, default) or a mapping.
759 item = None # in case names is empty
760 for item in names:
761 if isinstance(item, basestring):
762 # mapping
763 field_name, field_index = item, names[item]
764 else:
765 # non-mapping
766 if len(item) == 2:
767 field_name, field_index = item
768 else:
769 field_name, field_index = item[0], item[1:]
770 clsdict[field_name] = field_index
771 if type is not None:
772 if not isinstance(type, tuple):
773 type = (type, )
774 bases = type + bases
775 namedtuple_class = metacls.__new__(metacls, class_name, bases, clsdict)
776
777 # TODO: replace the frame hack if a blessed way to know the calling
778 # module is ever developed
779 if module is None:
780 try:
781 module = _sys._getframe(1).f_globals['__name__']
782 except (AttributeError, ValueError, KeyError):
783 pass
784 if module is None:
785 _make_class_unpicklable(namedtuple_class)
786 else:
787 namedtuple_class.__module__ = module
788
789 return namedtuple_class
790 else:
791 # instantiate a subclass
792 namedtuple_instance = cls.__new__(cls, *args, **kwds)
793 if isinstance(namedtuple_instance, cls):
794 namedtuple_instance.__init__(*args, **kwds)
795 return namedtuple_instance
796
797 @property
798 def __fields__(cls):
799 return list(cls._fields_)
800 # collections.namedtuple compatibility
801 _fields = __fields__
802
803 @property
804 def __aliases__(cls):
805 return list(cls._aliases_)
806
807 def __repr__(cls):
808 return "<NamedTuple %r>" % (cls.__name__, )
809
810 temp_namedtuple_dict = {}
811 temp_namedtuple_dict['__doc__'] = "NamedTuple base class.\n\n Derive from this class to define new NamedTuples.\n\n"
812
813 def __new__(cls, *args, **kwds):
814 if cls._size_ is TupleSize.fixed and len(args) > cls._defined_len_:
815 raise TypeError('%d fields expected, %d received' % (cls._defined_len_, len(args)))
816 unknown = set(kwds) - set(cls._fields_) - set(cls._aliases_)
817 if unknown:
818 raise TypeError('unknown fields: %r' % (unknown, ))
819 final_args = list(args) + [undefined] * (len(cls.__fields__) - len(args))
820 for field, value in kwds.items():
821 index = getattr(cls, field).index
822 if final_args[index] != undefined:
823 raise TypeError('field %s specified more than once' % field)
824 final_args[index] = value
825 missing = []
826 for index, value in enumerate(final_args):
827 if value is undefined:
828 # look for default values
829 name = cls.__fields__[index]
830 default = getattr(cls, name).default
831 if default is undefined:
832 missing.append(name)
833 else:
834 final_args[index] = default
835 if missing:
836 if cls._size_ in (TupleSize.fixed, TupleSize.minimum):
837 raise TypeError('values not provided for field(s): %s' % ', '.join(missing))
838 while final_args and final_args[-1] is undefined:
839 final_args.pop()
840 missing.pop()
841 if cls._size_ is not TupleSize.variable or undefined in final_args:
842 raise TypeError('values not provided for field(s): %s' % ', '.join(missing))
843 return tuple.__new__(cls, tuple(final_args))
844
845 temp_namedtuple_dict['__new__'] = __new__
846 del __new__
847
848 def __reduce_ex__(self, proto):
849 return self.__class__, tuple(getattr(self, f) for f in self._fields_)
850 temp_namedtuple_dict['__reduce_ex__'] = __reduce_ex__
851 del __reduce_ex__
852
853 def __repr__(self):
854 if len(self) == len(self._fields_):
855 return "%s(%s)" % (
856 self.__class__.__name__, ', '.join(['%s=%r' % (f, o) for f, o in zip(self._fields_, self)])
857 )
858 else:
859 return '%s(%s)' % (self.__class__.__name__, ', '.join([repr(o) for o in self]))
860 temp_namedtuple_dict['__repr__'] = __repr__
861 del __repr__
862
863 def __str__(self):
864 return "%s(%s)" % (
865 self.__class__.__name__, ', '.join(['%r' % (getattr(self, f), ) for f in self._fields_])
866 )
867 temp_namedtuple_dict['__str__'] = __str__
868 del __str__
869
870 ## compatibility methods with stdlib namedtuple
871 @property
872 def __aliases__(self):
873 return list(self.__class__._aliases_)
874 temp_namedtuple_dict['__aliases__'] = __aliases__
875 del __aliases__
876
877 @property
878 def __fields__(self):
879 return list(self.__class__._fields_)
880 temp_namedtuple_dict['__fields__'] = __fields__
881 temp_namedtuple_dict['_fields'] = __fields__
882 del __fields__
883
884 def _make(cls, iterable, new=None, len=None):
885 return cls.__new__(cls, *iterable)
886 temp_namedtuple_dict['_make'] = classmethod(_make)
887 del _make
888
889 def _asdict(self):
890 return OrderedDict(zip(self._fields_, self))
891 temp_namedtuple_dict['_asdict'] = _asdict
892 del _asdict
893
894 def _replace(self, **kwds):
895 current = self._asdict()
896 current.update(kwds)
897 return self.__class__(**current)
898 temp_namedtuple_dict['_replace'] = _replace
899 del _replace
900
901 NamedTuple = NamedTupleMeta('NamedTuple', (object, ), temp_namedtuple_dict)
902 del temp_namedtuple_dict
903
904 # defined now for immediate use
905
906 def enumsort(things):
907 """
908 sorts things by value if all same type; otherwise by name
909 """
910 if not things:
911 return things
912 sort_type = type(things[0])
913 if not issubclass(sort_type, tuple):
914 # direct sort or type error
915 if not all((type(v) is sort_type) for v in things[1:]):
916 raise TypeError('cannot sort items of different types')
917 return sorted(things)
918 else:
919 # expecting list of (name, value) tuples
920 sort_type = type(things[0][1])
921 try:
922 if all((type(v[1]) is sort_type) for v in things[1:]):
923 return sorted(things, key=lambda i: i[1])
924 else:
925 raise TypeError('try name sort instead')
926 except TypeError:
927 return sorted(things, key=lambda i: i[0])
928
929 def export(collection, namespace=None):
930 """
931 export([collection,] namespace) -> Export members to target namespace.
932
933 If collection is not given, act as a decorator.
934 """
935 if namespace is None:
936 namespace = collection
937 def export_decorator(collection):
938 return export(collection, namespace)
939 return export_decorator
940 elif issubclass(collection, NamedConstant):
941 for n, c in collection.__dict__.items():
942 if isinstance(c, NamedConstant):
943 namespace[n] = c
944 elif issubclass(collection, Enum):
945 data = collection.__members__.items()
946 for n, m in data:
947 namespace[n] = m
948 else:
949 raise TypeError('%r is not a supported collection' % (collection,) )
950 return collection
951
952 # Constants used in Enum
953
954 @export(globals())
955 class EnumConstants(NamedConstant):
956 AutoValue = constant('autovalue', 'values are automatically created from _generate_next_value_')
957 AutoNumber = constant('autonumber', 'integer value is prepended to members, beginning from START')
958 MultiValue = constant('multivalue', 'each member can have several values')
959 NoAlias = constant('noalias', 'duplicate valued members are distinct, not aliased')
960 Unique = constant('unique', 'duplicate valued members are not allowed')
961
962
963 ############
964 # Enum stuff
965 ############
966
967 # Dummy value for Enum as EnumMeta explicity checks for it, but of course until
968 # EnumMeta finishes running the first time the Enum class doesn't exist. This
969 # is also why there are checks in EnumMeta like `if Enum is not None`
970 Enum = Flag = None
971
972 class enum(object):
973 """
974 Helper class to track args, kwds.
975 """
976 def __init__(self, *args, **kwds):
977 self._args = args
978 self._kwds = kwds.items()
979 self._hash = hash(args)
980 self.name = None
981
982 @property
983 def args(self):
984 return self._args
985
986 @property
987 def kwds(self):
988 return dict([(k, v) for k, v in self._kwds])
989
990 def __hash__(self):
991 return self._hash
992
993 def __eq__(self, other):
994 if not isinstance(other, self.__class__):
995 return NotImplemented
996 return self.args == other.args and self.kwds == other.kwds
997
998 def __ne__(self, other):
999 if not isinstance(other, self.__class__):
1000 return NotImplemented
1001 return self.args != other.args or self.kwds != other.kwds
1002
1003 def __repr__(self):
1004 final = []
1005 args = ', '.join(['%r' % (a, ) for a in self.args])
1006 if args:
1007 final.append(args)
1008 kwds = ', '.join([('%s=%r') % (k, v) for k, v in enumsort(list(self.kwds.items()))])
1009 if kwds:
1010 final.append(kwds)
1011 return 'enum(%s)' % ', '.join(final)
1012
1013 _auto_null = object()
1014 class auto(enum):
1015 """
1016 Instances are replaced with an appropriate value in Enum class suites.
1017 """
1018 _value = _auto_null
1019 _operations = []
1020
1021 def __and__(self, other):
1022 new_auto = self.__class__()
1023 new_auto._operations = self._operations[:]
1024 new_auto._operations.append((_and_, (self, other)))
1025 return new_auto
1026
1027 def __rand__(self, other):
1028 new_auto = self.__class__()
1029 new_auto._operations = self._operations[:]
1030 new_auto._operations.append((_and_, (other, self)))
1031 return new_auto
1032
1033 def __invert__(self):
1034 new_auto = self.__class__()
1035 new_auto._operations = self._operations[:]
1036 new_auto._operations.append((_inv_, (self,)))
1037 return new_auto
1038
1039 def __or__(self, other):
1040 new_auto = self.__class__()
1041 new_auto._operations = self._operations[:]
1042 new_auto._operations.append((_or_, (self, other)))
1043 return new_auto
1044
1045 def __ror__(self, other):
1046 new_auto = self.__class__()
1047 new_auto._operations = self._operations[:]
1048 new_auto._operations.append((_or_, (other, self)))
1049 return new_auto
1050
1051 def __xor__(self, other):
1052 new_auto = self.__class__()
1053 new_auto._operations = self._operations[:]
1054 new_auto._operations.append((_xor_, (self, other)))
1055 return new_auto
1056
1057 def __rxor__(self, other):
1058 new_auto = self.__class__()
1059 new_auto._operations = self._operations[:]
1060 new_auto._operations.append((_xor_, (other, self)))
1061 return new_auto
1062
1063 def __abs__(self):
1064 new_auto = self.__class__()
1065 new_auto._operations = self._operations[:]
1066 new_auto._operations.append((_abs_, (self, )))
1067 return new_auto
1068
1069 def __add__(self, other):
1070 new_auto = self.__class__()
1071 new_auto._operations = self._operations[:]
1072 new_auto._operations.append((_add_, (self, other)))
1073 return new_auto
1074
1075 def __radd__(self, other):
1076 new_auto = self.__class__()
1077 new_auto._operations = self._operations[:]
1078 new_auto._operations.append((_add_, (other, self)))
1079 return new_auto
1080
1081 def __neg__(self):
1082 new_auto = self.__class__()
1083 new_auto._operations = self._operations[:]
1084 new_auto._operations.append((_neg_, (self, )))
1085 return new_auto
1086
1087 def __pos__(self):
1088 new_auto = self.__class__()
1089 new_auto._operations = self._operations[:]
1090 new_auto._operations.append((_pos_, (self, )))
1091 return new_auto
1092
1093 if pyver < 3:
1094 def __div__(self, other):
1095 new_auto = self.__class__()
1096 new_auto._operations = self._operations[:]
1097 new_auto._operations.append((_div_, (self, other)))
1098 return new_auto
1099
1100 def __rdiv__(self, other):
1101 new_auto = self.__class__()
1102 new_auto._operations = self._operations[:]
1103 new_auto._operations.append((_div_, (other, self)))
1104 return new_auto
1105
1106 def __floordiv__(self, other):
1107 new_auto = self.__class__()
1108 new_auto._operations = self._operations[:]
1109 new_auto._operations.append((_floordiv_, (self, other)))
1110 return new_auto
1111
1112 def __rfloordiv__(self, other):
1113 new_auto = self.__class__()
1114 new_auto._operations = self._operations[:]
1115 new_auto._operations.append((_floordiv_, (other, self)))
1116 return new_auto
1117
1118 def __truediv__(self, other):
1119 new_auto = self.__class__()
1120 new_auto._operations = self._operations[:]
1121 new_auto._operations.append((_truediv_, (self, other)))
1122 return new_auto
1123
1124 def __rtruediv__(self, other):
1125 new_auto = self.__class__()
1126 new_auto._operations = self._operations[:]
1127 new_auto._operations.append((_truediv_, (other, self)))
1128 return new_auto
1129
1130 def __lshift__(self, other):
1131 new_auto = self.__class__()
1132 new_auto._operations = self._operations[:]
1133 new_auto._operations.append((_lshift_, (self, other)))
1134 return new_auto
1135
1136 def __rlshift__(self, other):
1137 new_auto = self.__class__()
1138 new_auto._operations = self._operations[:]
1139 new_auto._operations.append((_lshift_, (other, self)))
1140 return new_auto
1141
1142 def __rshift__(self, other):
1143 new_auto = self.__class__()
1144 new_auto._operations = self._operations[:]
1145 new_auto._operations.append((_rshift_, (self, other)))
1146 return new_auto
1147
1148 def __rrshift__(self, other):
1149 new_auto = self.__class__()
1150 new_auto._operations = self._operations[:]
1151 new_auto._operations.append((_rshift_, (other, self)))
1152 return new_auto
1153
1154 def __mod__(self, other):
1155 new_auto = self.__class__()
1156 new_auto._operations = self._operations[:]
1157 new_auto._operations.append((_mod_, (self, other)))
1158 return new_auto
1159
1160 def __rmod__(self, other):
1161 new_auto = self.__class__()
1162 new_auto._operations = self._operations[:]
1163 new_auto._operations.append((_mod_, (other, self)))
1164 return new_auto
1165
1166 def __mul__(self, other):
1167 new_auto = self.__class__()
1168 new_auto._operations = self._operations[:]
1169 new_auto._operations.append((_mul_, (self, other)))
1170 return new_auto
1171
1172 def __rmul__(self, other):
1173 new_auto = self.__class__()
1174 new_auto._operations = self._operations[:]
1175 new_auto._operations.append((_mul_, (other, self)))
1176 return new_auto
1177
1178 def __pow__(self, other):
1179 new_auto = self.__class__()
1180 new_auto._operations = self._operations[:]
1181 new_auto._operations.append((_pow_, (self, other)))
1182 return new_auto
1183
1184 def __rpow__(self, other):
1185 new_auto = self.__class__()
1186 new_auto._operations = self._operations[:]
1187 new_auto._operations.append((_pow_, (other, self)))
1188 return new_auto
1189
1190 def __sub__(self, other):
1191 new_auto = self.__class__()
1192 new_auto._operations = self._operations[:]
1193 new_auto._operations.append((_sub_, (self, other)))
1194 return new_auto
1195
1196 def __rsub__(self, other):
1197 new_auto = self.__class__()
1198 new_auto._operations = self._operations[:]
1199 new_auto._operations.append((_sub_, (other, self)))
1200 return new_auto
1201
1202
1203
1204 @property
1205 def value(self):
1206 if self._value is not _auto_null and self._operations:
1207 raise TypeError('auto() object out of sync')
1208 elif self._value is _auto_null and not self._operations:
1209 return self._value
1210 elif self._value is not _auto_null:
1211 return self._value
1212 else:
1213 return self._resolve()
1214
1215 @value.setter
1216 def value(self, value):
1217 if self._operations:
1218 value = self._resolve(value)
1219 self._value = value
1220
1221 def _resolve(self, base_value=None):
1222 cls = self.__class__
1223 for op, params in self._operations:
1224 values = []
1225 for param in params:
1226 if isinstance(param, cls):
1227 if param.value is _auto_null:
1228 if base_value is None:
1229 return _auto_null
1230 else:
1231 values.append(base_value)
1232 else:
1233 values.append(param.value)
1234 else:
1235 values.append(param)
1236 value = op(*values)
1237 self._operations[:] = []
1238 self._value = value
1239 return value
1240
1241 class _EnumDict(dict):
1242 """Track enum member order and ensure member names are not reused.
1243
1244 EnumMeta will use the names found in self._member_names as the
1245 enumeration member names.
1246 """
1247 def __init__(self, cls_name, settings, start, constructor_init, constructor_start):
1248 super(_EnumDict, self).__init__()
1249 self._cls_name = cls_name
1250 self._constructor_init = constructor_init
1251 self._constructor_start = constructor_start
1252 # for Flag enumerations, we may need to get the _init_ from __new__
1253 self._new_to_init = False
1254 # list of enum members
1255 self._member_names = []
1256 self._settings = settings
1257 autonumber = AutoNumber in settings
1258 autovalue = AutoValue in settings
1259 multivalue = MultiValue in settings
1260 if autonumber and start is None:
1261 # starting value for AutoNumber
1262 start = 1
1263 elif start is not None and not autonumber:
1264 autonumber = True
1265 if start is not None:
1266 self._value = start - 1
1267 else:
1268 self._value = None
1269 # when the magic turns off
1270 self._locked = not (autovalue or autonumber)
1271 # if auto or autonumber
1272 self._autovalue = autovalue
1273 self._autonumber = autonumber
1274 # if multiple values are allowed
1275 self._multivalue = multivalue
1276 # if init fields are specified
1277 self._init = None
1278 # list of temporary names
1279 self._ignore = []
1280 self._ignore_init_done = False
1281 # if _sunder_ values can be changed via the class body
1282 self._allow_init = True
1283 self._last_values = []
1284
1285 def __getitem__(self, key):
1286 if key == self._cls_name and self._cls_name not in self:
1287 return enum
1288 elif key == '_auto_on_':
1289 self._locked = False
1290 if not self._autonumber:
1291 self._autovalue = True
1292 return None
1293 elif key == '_auto_off_':
1294 self._locked = True
1295 return None
1296 elif (
1297 self._locked
1298 or key in self
1299 or key in self._ignore
1300 or _is_sunder(key)
1301 or _is_dunder(key)
1302 ):
1303 return super(_EnumDict, self).__getitem__(key)
1304 elif self._autonumber:
1305 try:
1306 # try to generate the next value
1307 value = self._value + 1
1308 self._value += 1
1309 except:
1310 # couldn't work the magic, report error
1311 raise KeyError('%s not found' % (key,))
1312 elif self._autovalue:
1313 value = self._generate_next_value(key, 1, len(self._member_names), self._last_values[:])
1314 else:
1315 raise Exception('neither AutoNumber nor AutoValue set -- why am I here?')
1316 self.__setitem__(key, value)
1317 return value
1318
1319 def __setitem__(self, key, value):
1320 """Changes anything not sundured, dundered, nor a descriptor.
1321
1322 If an enum member name is used twice, an error is raised; duplicate
1323 values are not checked for.
1324
1325 Single underscore (sunder) names are reserved.
1326 """
1327 if _is_internal_class(self._cls_name, value):
1328 pass
1329 elif _is_sunder(key):
1330 if key not in (
1331 '_init_', '_settings_', '_order_', '_ignore_', '_start_',
1332 '_create_pseudo_member_', '_create_pseudo_member_values_',
1333 '_generate_next_value_',
1334 '_missing_', '_missing_value_', '_missing_name_',
1335 ):
1336 raise ValueError('_names_ are reserved for Enum use')
1337 elif not self._allow_init and key not in (
1338 'create_pseudo_member_', '_missing_', '_missing_value_', '_missing_name_',
1339 ):
1340 # sunder is used during creation, must be specified first
1341 raise ValueError('cannot set %r after init phase' % (key, ))
1342 elif key == '_ignore_':
1343 if self._ignore_init_done:
1344 raise TypeError('ignore can only be specified once')
1345 if isinstance(value, basestring):
1346 value = value.split()
1347 else:
1348 value = list(value)
1349 self._ignore = value
1350 already = set(value) & set(self._member_names)
1351 if already:
1352 raise ValueError('_ignore_ cannot specify already set names: %r' % (already, ))
1353 self._ignore_init_done = True
1354 elif key == '_start_':
1355 if self._constructor_start:
1356 raise TypeError('start specified in constructor and class body')
1357 if value is None:
1358 self._value = None
1359 self._autonumber = False
1360 if not self._autovalue:
1361 self._locked = True
1362 else:
1363 self._value = value - 1
1364 self._locked = False
1365 self._autonumber = True
1366 elif key == '_settings_':
1367 if not isinstance(value, (set, tuple)):
1368 value = (value, )
1369 if not isinstance(value, set):
1370 value = set(value)
1371 self._settings |= value
1372 if NoAlias in value and Unique in value:
1373 raise TypeError('cannot specify both NoAlias and Unique')
1374 elif MultiValue in value and NoAlias in value:
1375 raise TypeError('cannot specify both MultiValue and NoAlias')
1376 elif AutoValue in value and AutoNumber in value:
1377 raise TypeError('cannot specify both AutoValue and AutoNumber')
1378 allowed_settings = dict.fromkeys(['autovalue', 'autonumber', 'noalias', 'unique', 'multivalue'])
1379 for arg in value:
1380 if arg not in allowed_settings:
1381 raise TypeError('unknown qualifier: %r (from %r)' % (arg, value))
1382 allowed_settings[arg] = True
1383 self._multivalue = allowed_settings['multivalue']
1384 self._autovalue = allowed_settings['autovalue']
1385 self._autonumber = allowed_settings['autonumber']
1386 self._locked = not (self._autonumber or self._autovalue)
1387 if self._autovalue and not self._ignore_init_done:
1388 self._ignore = ['property', 'classmethod', 'staticmethod']
1389 if self._autonumber and self._value is None:
1390 self._value = 0
1391 if self._autonumber and self._init and self._init[0:1] == ['value']:
1392 self._init.pop(0)
1393 value = tuple(self._settings)
1394 elif key == '_init_':
1395 if self._constructor_init:
1396 raise TypeError('init specified in constructor and in class body')
1397 _init_ = value
1398 if isinstance(_init_, basestring):
1399 _init_ = _init_.replace(',',' ').split()
1400 if _init_[0:1] == ['value'] and self._autonumber:
1401 _init_.pop(0)
1402 self._init = _init_
1403 elif key == '_generate_next_value_':
1404 if isinstance(value, staticmethod):
1405 gnv = value.__func__
1406 elif isinstance(value, classmethod):
1407 raise TypeError('_generate_next_value should be a staticmethod, not a classmethod')
1408 else:
1409 gnv = value
1410 value = staticmethod(value)
1411 setattr(self, '_generate_next_value', gnv)
1412 self._auto_args = _check_auto_args(value)
1413 elif _is_dunder(key):
1414 if key == '__order__':
1415 key = '_order_'
1416 if not self._allow_init:
1417 # _order_ is used during creation, must be specified first
1418 raise ValueError('cannot set %r after init phase' % (key, ))
1419 elif key == '__new__' and self._new_to_init:
1420 # ArgSpec(args=[...], varargs=[...], keywords=[...], defaults=[...]
1421 if isinstance(value, staticmethod):
1422 value = value.__func__
1423 new_args = getargspec(value)[0][1:]
1424 self._init = new_args
1425 if _is_descriptor(value):
1426 self._locked = True
1427 elif key in self._member_names:
1428 # descriptor overwriting an enum?
1429 raise TypeError('attempt to reuse name: %r' % (key, ))
1430 elif key in self._ignore:
1431 pass
1432 elif not _is_descriptor(value):
1433 self._allow_init = False
1434 if key in self:
1435 # enum overwriting a descriptor?
1436 raise TypeError('%s already defined as: %r' % (key, self[key]))
1437 if self._multivalue:
1438 # make sure it's a tuple
1439 if not isinstance(value, tuple):
1440 value = (value, )
1441 # do we need to calculate the next value?
1442 if self._autonumber:
1443 if self._init:
1444 target_length = len(self._init)
1445 if self._init[0] != 'value':
1446 target_length += 1
1447 if len(value) != target_length:
1448 value = (self._value + 1, ) + value
1449 else:
1450 try:
1451 value = (self._value + 1, ) + value
1452 except TypeError:
1453 pass
1454 if self._autonumber:
1455 self._value = value[0]
1456 elif self._autovalue and self._init and not isinstance(value, auto):
1457 # call generate iff init is specified and calls for more values than are present
1458 target_values = len(self._init)
1459 if not isinstance(value, tuple):
1460 value = (value, )
1461 source_values = len(value)
1462 if target_values != source_values:
1463 gnv = self._generate_next_value
1464 if self._auto_args:
1465 value = gnv(
1466 key, 1,
1467 len(self._member_names),
1468 self._last_values[:],
1469 *value
1470 )
1471 else:
1472 value = gnv(
1473 key,
1474 1,
1475 len(self._member_names),
1476 self._last_values[:],
1477 )
1478
1479 elif self._autonumber and not self._locked:
1480 # convert any auto instances to integers
1481 if isinstance(value, auto):
1482 value = self._value + 1
1483 elif isinstance(value, basestring):
1484 pass
1485 else:
1486 try:
1487 new_value = []
1488 for v in value:
1489 if isinstance(v, auto):
1490 new_value.append(self._value + 1)
1491 else:
1492 new_value.append(v)
1493 value = tuple(new_value)
1494 except TypeError:
1495 # value wasn't iterable
1496 pass
1497 if isinstance(value, int):
1498 self._value = value
1499 elif isinstance(value, tuple):
1500 if self._init is None:
1501 # old behavior -> if first item is int, use it as value
1502 # otherwise, generate a value and prepend it
1503 if value and isinstance(value[0], baseinteger):
1504 self._value = value[0]
1505 else:
1506 self._value += 1
1507 value = (self._value, ) + value
1508 elif len(value) == len(self._init):
1509 # provide actual value for member
1510 self._value += 1
1511 value = (self._value, ) + value
1512 elif 'value' not in self._init and len(value) == len(self._init) + 1:
1513 # actual value for member is provided
1514 self._value = value[0]
1515 elif 'value' in self._init and len(value) == len(self._init) - 1:
1516 count = self._value + 1
1517 value = count, value
1518 self._value = count
1519 else:
1520 # mismatch
1521 raise TypeError('%s: number of fields provided do not match init' % key)
1522 else:
1523 if self._init is not None and (len(self._init) != 1 or 'value' in self._init):
1524 raise TypeError('%s: number of fields provided do not match init' % key)
1525 count = self._value + 1
1526 value = count, value
1527 self._value = count
1528 elif isinstance(value, auto):
1529 # if AutoNumber set use built-in value, not _generate_next_value_
1530 if self._autonumber:
1531 value = self._value + 1
1532 self._value = value
1533 else:
1534 if value.value == _auto_null:
1535 gnv = self._generate_next_value
1536 prev_values = []
1537 for v in self._last_values:
1538 if isinstance(v, auto):
1539 prev_values.append(v.value)
1540 else:
1541 prev_values.append(v)
1542 if isinstance(gnv, staticmethod):
1543 gnv = gnv.__func__
1544 if self._auto_args:
1545 value.value = gnv(
1546 key,
1547 1,
1548 len(self._member_names),
1549 prev_values,
1550 *value.args,
1551 **value.kwds
1552 )
1553 else:
1554 value.value = gnv(
1555 key,
1556 1,
1557 len(self._member_names),
1558 prev_values,
1559 )
1560 elif isinstance(value, enum):
1561 value.name = key
1562 else:
1563 pass
1564 self._member_names.append(key)
1565 else:
1566 # not a new member, turn off the autoassign magic
1567 self._locked = True
1568 self._allow_init = False
1569 if not _is_sunder(key) and not _is_dunder(key) and not _is_descriptor(value):
1570 if (self._autonumber or self._multivalue) and isinstance(value, tuple):
1571 self._last_values.append(value[0])
1572 else:
1573 self._last_values.append(value)
1574 super(_EnumDict, self).__setitem__(key, value)
1575
1576
1577 no_arg = object()
1578 class EnumMeta(StdlibEnumMeta or type):
1579 """Metaclass for Enum"""
1580 @classmethod
1581 def __prepare__(metacls, cls, bases, init=None, start=None, settings=()):
1582 # settings are a combination of current and all past settings
1583 constructor_init = init is not None
1584 constructor_start = start is not None
1585 if not isinstance(settings, tuple):
1586 settings = settings,
1587 settings = set(settings)
1588 generate = None
1589 order = None
1590 # inherit previous flags
1591 member_type, first_enum = metacls._get_mixins_(bases)
1592 if first_enum is not None:
1593 settings |= first_enum._settings_
1594 init = init or first_enum._auto_init_
1595 order = first_enum._order_function_
1596 if start is None:
1597 start = first_enum._start_
1598 generate = getattr(first_enum, '_generate_next_value_', None)
1599 generate = getattr(generate, 'im_func', generate)
1600 # check for custom settings
1601 if NoAlias in settings and Unique in settings:
1602 raise TypeError('cannot specify both NoAlias and Unique')
1603 elif MultiValue in settings and NoAlias in settings:
1604 raise TypeError('cannot specify both MultiValue and NoAlias')
1605 elif AutoValue in settings and AutoNumber in settings:
1606 raise TypeError('cannot specify both AutoValue and AutoNumber')
1607 allowed_settings = dict.fromkeys(['autovalue', 'autonumber', 'noalias', 'unique', 'multivalue'])
1608 for arg in settings:
1609 if arg not in allowed_settings:
1610 raise TypeError('unknown qualifier: %r' % (arg, ))
1611 allowed_settings[arg] = True
1612 enum_dict = _EnumDict(cls_name=cls, settings=settings, start=start, constructor_init=constructor_init, constructor_start=constructor_start)
1613 if settings & set([AutoValue, AutoNumber]) or start is not None:
1614 enum_dict['_ignore_'] = ['property', 'classmethod', 'staticmethod']
1615 enum_dict._ignore_init_done = False
1616 if generate:
1617 enum_dict['_generate_next_value_'] = generate
1618 if init is not None:
1619 if isinstance(init, basestring):
1620 init = init.replace(',',' ').split()
1621 if init[0:1] == ['value'] and AutoNumber in settings:
1622 init.pop(0)
1623 enum_dict._init = init
1624 elif Flag is not None and any(issubclass(b, Flag) for b in bases) and member_type not in (int, object):
1625 enum_dict._new_to_init = True
1626 if Flag in bases:
1627 # only happens on first mixin with Flag
1628 def _generate_next_value_(name, start, count, values, *args, **kwds):
1629 return (2 ** count, ) + args
1630 enum_dict['_generate_next_value_'] = staticmethod(_generate_next_value_)
1631 def __new__(cls, flag_value, type_value):
1632 obj = member_type.__new__(cls, type_value)
1633 obj._value_ = flag_value
1634 return obj
1635 enum_dict['__new__'] = __new__
1636 else:
1637 try:
1638 new_args = getargspec(first_enum.__new_member__)[0][1:]
1639 enum_dict._init = new_args
1640 except TypeError:
1641 pass
1642 if order is not None:
1643 enum_dict['_order_'] = staticmethod(order)
1644 return enum_dict
1645
1646 def __init__(cls, *args , **kwds):
1647 super(EnumMeta, cls).__init__(*args)
1648
1649 def __new__(metacls, cls, bases, clsdict, init=None, start=None, settings=()):
1650 # handle py2 case first
1651 if type(clsdict) is not _EnumDict:
1652 # py2 ard/or functional API gyrations
1653 init = clsdict.pop('_init_', None)
1654 start = clsdict.pop('_start_', None)
1655 settings = clsdict.pop('_settings_', ())
1656 _order_ = clsdict.pop('_order_', clsdict.pop('__order__', None))
1657 _ignore_ = clsdict.pop('_ignore_', None)
1658 _create_pseudo_member_ = clsdict.pop('_create_pseudo_member_', None)
1659 _create_pseudo_member_values_ = clsdict.pop('_create_pseudo_member_values_', None)
1660 _generate_next_value_ = clsdict.pop('_generate_next_value_', None)
1661 _missing_ = clsdict.pop('_missing_', None)
1662 _missing_value_ = clsdict.pop('_missing_value_', None)
1663 _missing_name_ = clsdict.pop('_missing_name_', None)
1664 __new__ = clsdict.pop('__new__', None)
1665 enum_members = dict([
1666 (k, v) for (k, v) in clsdict.items()
1667 if not (_is_sunder(k) or _is_dunder(k) or _is_descriptor(v))
1668 ])
1669 original_dict = clsdict
1670 clsdict = metacls.__prepare__(cls, bases, init=init, start=start, settings=settings)
1671 init = init or clsdict._init
1672 if _order_ is None:
1673 _order_ = clsdict.get('_order_')
1674 if _order_ is not None:
1675 _order_ = _order_.__get__(cls)
1676 if isinstance(original_dict, OrderedDict):
1677 calced_order = original_dict
1678 elif _order_ is None:
1679 calced_order = [name for (name, value) in enumsort(list(enum_members.items()))]
1680 elif isinstance(_order_, basestring):
1681 calced_order = _order_ = _order_.replace(',', ' ').split()
1682 elif callable(_order_):
1683 if init:
1684 if not isinstance(init, basestring):
1685 init = ' '.join(init)
1686 member = NamedTuple('member', init and 'name ' + init or ['name', 'value'])
1687 calced_order = []
1688 for name, value in enum_members.items():
1689 if init:
1690 if not isinstance(value, tuple):
1691 value = (value, )
1692 name_value = (name, ) + value
1693 else:
1694 name_value = tuple((name, value))
1695 if member._defined_len_ != len(name_value):
1696 raise TypeError('%d values expected (%s), %d received (%s)' % (
1697 member._defined_len_,
1698 ', '.join(member._fields_),
1699 len(name_value),
1700 ', '.join([repr(v) for v in name_value]),
1701 ))
1702 calced_order.append(member(*name_value))
1703 calced_order = [m.name for m in sorted(calced_order, key=_order_)]
1704 else:
1705 calced_order = _order_
1706 for name in (
1707 '_ignore_', '_create_pseudo_member_', '_create_pseudo_member_values_',
1708 '_generate_next_value_', '_order_', '__new__',
1709 '_missing_', '_missing_value_', '_missing_name_',
1710 ):
1711 attr = locals()[name]
1712 if attr is not None:
1713 clsdict[name] = attr
1714 # now add members
1715 for k in calced_order:
1716 clsdict[k] = original_dict[k]
1717 for k, v in original_dict.items():
1718 if k not in calced_order:
1719 clsdict[k] = v
1720 del _order_, _ignore_, _create_pseudo_member_, _create_pseudo_member_values_,
1721 del _generate_next_value_, _missing_, _missing_value_, _missing_name_
1722
1723 # resume normal path
1724 if clsdict._new_to_init:
1725 # remove calculated _init_ as it's no longer needed
1726 clsdict._init = None
1727 clsdict._locked = True
1728 member_type, first_enum = metacls._get_mixins_(bases)
1729 _order_ = clsdict.pop('_order_', None)
1730 if isinstance(_order_, basestring):
1731 _order_ = _order_.replace(',',' ').split()
1732 init = clsdict._init
1733 start = clsdict._value
1734 settings = clsdict._settings
1735 if start is not None:
1736 start += 1
1737 creating_init = []
1738 auto_init = False
1739 if init is None and (AutoNumber in settings or start is not None):
1740 creating_init = ['value']
1741 elif init is not None:
1742 auto_init = True
1743 if (AutoNumber in settings or start is not None) and 'value' not in init:
1744 creating_init = ['value'] + init
1745 else:
1746 creating_init = init[:]
1747 autonumber = AutoNumber in settings
1748 autovalue = AutoValue in settings
1749 multivalue = MultiValue in settings
1750 noalias = NoAlias in settings
1751 unique = Unique in settings
1752 # an Enum class cannot be mixed with other types (int, float, etc.) if
1753 # it has an inherited __new__ unless a new __new__ is defined (or
1754 # the resulting class will fail).
1755 # an Enum class is final once enumeration items have been defined;
1756 #
1757 # remove any keys listed in _ignore_
1758 clsdict.setdefault('_ignore_', []).append('_ignore_')
1759 ignore = clsdict['_ignore_']
1760 for key in ignore:
1761 clsdict.pop(key, None)
1762 # get the method to create enum members
1763 __new__, save_new, new_uses_args = metacls._find_new_(
1764 clsdict,
1765 member_type,
1766 first_enum,
1767 )
1768 # save enum items into separate mapping so they don't get baked into
1769 # the new class
1770 enum_members = dict((k, clsdict[k]) for k in clsdict._member_names)
1771 for name in clsdict._member_names:
1772 del clsdict[name]
1773 # move skipped values out of the descriptor, and add names to DynamicAttributes
1774 for name, obj in clsdict.items():
1775 if isinstance(obj, nonmember):
1776 dict.__setitem__(clsdict, name, obj.value)
1777 elif isinstance(obj, enum_property):
1778 obj.name = name
1779 # check for illegal enum names (any others?)
1780 invalid_names = set(enum_members) & set(['mro', ''])
1781 if invalid_names:
1782 raise ValueError('Invalid enum member name(s): %s' % (
1783 ', '.join(invalid_names), ))
1784 # create our new Enum type
1785 enum_class = type.__new__(metacls, cls, bases, clsdict)
1786 enum_class._member_names_ = [] # names in random order
1787 enum_class._member_map_ = OrderedDict()
1788 enum_class._member_type_ = member_type
1789 # save current flags for subclasses
1790 enum_class._settings_ = settings
1791 enum_class._start_ = start
1792 enum_class._auto_init_ = _auto_init_ = init
1793 enum_class._order_function_ = None
1794 if 'value' in creating_init and creating_init[0] != 'value':
1795 raise TypeError("'value', if specified, must be the first item in 'init'")
1796 # save attributes from super classes so we know if we can take
1797 # the shortcut of storing members in the class dict
1798 base_attributes = set([a for b in enum_class.mro() for a in b.__dict__])
1799 # Reverse value->name map for hashable values.
1800 enum_class._value2member_map_ = {}
1801 enum_class._value2member_seq_ = ()
1802 # instantiate them, checking for duplicates as we go
1803 # we instantiate first instead of checking for duplicates first in case
1804 # a custom __new__ is doing something funky with the values -- such as
1805 # auto-numbering ;)
1806 if __new__ is None:
1807 __new__ = enum_class.__new__
1808 for member_name in clsdict._member_names:
1809 value = enum_members[member_name]
1810 if isinstance(value, auto):
1811 value = value.value
1812 kwds = {}
1813 new_args = ()
1814 init_args = ()
1815 extra_mv_args = ()
1816 if isinstance(value, enum):
1817 args = value.args
1818 kwds = value.kwds
1819 elif isinstance(value, Member):
1820 value = value.value
1821 args = (value, )
1822 elif not isinstance(value, tuple):
1823 args = (value, )
1824 else:
1825 args = value
1826 # possibilities
1827 #
1828 # - no init, multivalue -> __new__[0], __init__(*[:]), extra=[1:]
1829 # - init w/o value, multivalue -> __new__[0], __init__(*[:]), extra=[1:]
1830 #
1831 # - init w/value, multivalue -> __new__[0], __init__(*[1:]), extra=[1:]
1832 #
1833 # - init w/value, no multivalue -> __new__[0], __init__(*[1:]), extra=[]
1834 #
1835 # - init w/o value, no multivalue -> __new__[:], __init__(*[:]), extra=[]
1836 # - no init, no multivalue -> __new__[:], __init__(*[:]), extra=[]
1837 if multivalue or 'value' in creating_init:
1838 if multivalue:
1839 # when multivalue is True, creating_init can be anything
1840 new_args = args[0:1]
1841 extra_mv_args = args[1:]
1842 if 'value' in creating_init:
1843 init_args = args[1:]
1844 else:
1845 init_args = args
1846 else:
1847 # 'value' is definitely in creating_init
1848 new_args = args[0:1]
1849 if auto_init:
1850 # don't pass in value
1851 init_args = args[1:]
1852 else:
1853 # keep the all args for user-defined __init__
1854 init_args = args
1855 value = new_args[0]
1856 else:
1857 # either no creating_init, or it doesn't have 'value'
1858 new_args = args
1859 init_args = args
1860 if member_type is tuple: # special case for tuple enums
1861 new_args = (new_args, ) # wrap it one more time
1862 if not new_uses_args:
1863 enum_member = __new__(enum_class)
1864 if not hasattr(enum_member, '_value_'):
1865 enum_member._value_ = value
1866 else:
1867 enum_member = __new__(enum_class, *new_args, **kwds)
1868 if not hasattr(enum_member, '_value_'):
1869 enum_member._value_ = member_type(*new_args, **kwds)
1870 value = enum_member._value_
1871 enum_member._name_ = member_name
1872 enum_member.__objclass__ = enum_class
1873 enum_member.__init__(*init_args, **kwds)
1874 # If another member with the same value was already defined, the
1875 # new member becomes an alias to the existing one.
1876 if noalias:
1877 # unless NoAlias was specified
1878 enum_class._member_names_.append(member_name)
1879 else:
1880 nonunique = defaultdict(list)
1881 for name, canonical_member in enum_class._member_map_.items():
1882 if canonical_member.value == enum_member._value_:
1883 if unique:
1884 nonunique[name].append(member_name)
1885 continue
1886 enum_member = canonical_member
1887 break
1888 else:
1889 # Aliases don't appear in member names (only in __members__).
1890 enum_class._member_names_.append(member_name)
1891 if nonunique:
1892 # duplicates not allowed if Unique specified
1893 message = []
1894 for name, aliases in nonunique.items():
1895 bad_aliases = ','.join(aliases)
1896 message.append('%s --> %s' % (name, bad_aliases))
1897 raise ValueError(
1898 'duplicate names found in %r: %s' %
1899 (cls, '; '.join(message))
1900 )
1901 # performance boost for any member that would not shadow
1902 # an enum_property
1903 if member_name not in base_attributes:
1904 setattr(enum_class, member_name, enum_member)
1905 else:
1906 # otherwise make sure the thing being shadowed /is/ an
1907 # enum_property
1908 for parent in enum_class.mro()[1:]:
1909 if member_name in parent.__dict__:
1910 obj = parent.__dict__[member_name]
1911 if not isinstance(obj, enum_property):
1912 raise TypeError('%r already used: %r' % (member_name, obj))
1913 # we're good
1914 break
1915 # now add to _member_map_
1916 enum_class._member_map_[member_name] = enum_member
1917 values = (value, ) + extra_mv_args
1918 enum_member._values_ = values
1919 for value in values:
1920 # first check if value has already been used
1921 if multivalue and (
1922 value in enum_class._value2member_map_
1923 or any(v == value for (v, m) in enum_class._value2member_seq_)
1924 ):
1925 raise ValueError('%r has already been used' % (value, ))
1926 try:
1927 # This may fail if value is not hashable. We can't add the value
1928 # to the map, and by-value lookups for this value will be
1929 # linear.
1930 if noalias:
1931 raise TypeError('cannot use dict to store value')
1932 enum_class._value2member_map_[value] = enum_member
1933 except TypeError:
1934 enum_class._value2member_seq_ += ((value, enum_member), )
1935 # check for constants with auto() values
1936 for k, v in enum_class.__dict__.items():
1937 if isinstance(v, constant) and isinstance(v.value, auto):
1938 v.value = enum_class(v.value.value)
1939 # If a custom type is mixed into the Enum, and it does not know how
1940 # to pickle itself, pickle.dumps will succeed but pickle.loads will
1941 # fail. Rather than have the error show up later and possibly far
1942 # from the source, sabotage the pickle protocol for this class so
1943 # that pickle.dumps also fails.
1944 #
1945 # However, if the new class implements its own __reduce_ex__, do not
1946 # sabotage -- it's on them to make sure it works correctly. We use
1947 # __reduce_ex__ instead of any of the others as it is preferred by
1948 # pickle over __reduce__, and it handles all pickle protocols.
1949 unpicklable = False
1950 if '__reduce_ex__' not in clsdict:
1951 if member_type is not object:
1952 methods = ('__getnewargs_ex__', '__getnewargs__',
1953 '__reduce_ex__', '__reduce__')
1954 if not any(m in member_type.__dict__ for m in methods):
1955 _make_class_unpicklable(enum_class)
1956 unpicklable = True
1957
1958 # double check that repr and friends are not the mixin's or various
1959 # things break (such as pickle)
1960
1961 for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'):
1962 enum_class_method = enum_class.__dict__.get(name, None)
1963 if enum_class_method:
1964 # class has defined/imported/copied the method
1965 continue
1966 class_method = getattr(enum_class, name)
1967 obj_method = getattr(member_type, name, None)
1968 enum_method = getattr(first_enum, name, None)
1969 if obj_method is not None and obj_method == class_method:
1970 if name == '__reduce_ex__' and unpicklable:
1971 continue
1972 setattr(enum_class, name, enum_method)
1973
1974 # method resolution and int's are not playing nice
1975 # Python's less than 2.6 use __cmp__
1976
1977 if pyver < 2.6:
1978
1979 if issubclass(enum_class, int):
1980 setattr(enum_class, '__cmp__', getattr(int, '__cmp__'))
1981
1982 elif pyver < 3.0:
1983
1984 if issubclass(enum_class, int):
1985 for method in (
1986 '__le__',
1987 '__lt__',
1988 '__gt__',
1989 '__ge__',
1990 '__eq__',
1991 '__ne__',
1992 '__hash__',
1993 ):
1994 setattr(enum_class, method, getattr(int, method))
1995
1996 # replace any other __new__ with our own (as long as Enum is not None,
1997 # anyway) -- again, this is to support pickle
1998 if Enum is not None:
1999 # if the user defined their own __new__, save it before it gets
2000 # clobbered in case they subclass later
2001 if save_new:
2002 setattr(enum_class, '__new_member__', enum_class.__dict__['__new__'])
2003 setattr(enum_class, '__new__', Enum.__dict__['__new__'])
2004
2005 # py3 support for definition order (helps keep py2/py3 code in sync)
2006 if _order_:
2007 if isinstance(_order_, staticmethod):
2008 # _order_ = staticmethod.__get__(enum_class)
2009 # _order_ = getattr(_order_, 'im_func', _order_)
2010 _order_ = _order_.__func__
2011 if callable(_order_):
2012 # save order for future subclasses
2013 enum_class._order_function_ = staticmethod(_order_)
2014 # create ordered list for comparison
2015 _order_ = [m.name for m in sorted(enum_class, key=_order_)]
2016 if _order_ != enum_class._member_names_:
2017 raise TypeError('member order does not match _order_: %r %r' % (enum_class._member_names_, enum_class._member_map_.items()))
2018 return enum_class
2019
2020 def __bool__(cls):
2021 """
2022 classes/types should always be True.
2023 """
2024 return True
2025
2026 def __call__(cls, value=no_arg, names=None, module=None, type=None, start=1):
2027 """Either returns an existing member, or creates a new enum class.
2028
2029 This method is used both when an enum class is given a value to match
2030 to an enumeration member (i.e. Color(3)) and for the functional API
2031 (i.e. Color = Enum('Color', names='red green blue')).
2032
2033 When used for the functional API: `module`, if set, will be stored in
2034 the new class' __module__ attribute; `type`, if set, will be mixed in
2035 as the first base class.
2036
2037 Note: if `module` is not set this routine will attempt to discover the
2038 calling module by walking the frame stack; if this is unsuccessful
2039 the resulting class will not be pickleable.
2040 """
2041 if names is None: # simple value lookup
2042 return cls.__new__(cls, value)
2043 # otherwise, functional API: we're creating a new Enum type
2044 return cls._create_(value, names, module=module, type=type, start=start)
2045
2046 def __contains__(cls, member):
2047 if not isinstance(member, Enum):
2048 raise TypeError("%r (%r) is not an <aenum 'Enum'>" % (member, type(member)))
2049 if not isinstance(member, cls):
2050 return False
2051 return True
2052
2053 def __delattr__(cls, attr):
2054 # nicer error message when someone tries to delete an attribute
2055 # (see issue19025).
2056 if attr in cls._member_map_:
2057 raise AttributeError(
2058 "%s: cannot delete Enum member %r." % (cls.__name__, attr),
2059 )
2060 if isinstance(_get_attr_from_chain(cls, attr), constant):
2061 raise AttributeError(
2062 "%s: cannot delete constant %r" % (cls.__name__, attr),
2063 )
2064 super(EnumMeta, cls).__delattr__(attr)
2065
2066 def __dir__(self):
2067 return (['__class__', '__doc__', '__members__', '__module__'] +
2068 self._member_names_)
2069
2070 @property
2071 def __members__(cls):
2072 """Returns a mapping of member name->value.
2073
2074 This mapping lists all enum members, including aliases. Note that this
2075 is a copy of the internal mapping.
2076 """
2077 return cls._member_map_.copy()
2078
2079 def __getitem__(cls, name):
2080 try:
2081 return cls._member_map_[name]
2082 except KeyError:
2083 exc = _sys.exc_info()[1]
2084 if issubclass(cls, Flag) and '|' in name:
2085 try:
2086 # may be an __or__ed name
2087 result = cls(0)
2088 for n in name.split('|'):
2089 result |= cls[n]
2090 return result
2091 except KeyError:
2092 raise exc
2093 result = cls._missing_name_(name)
2094 if isinstance(result, cls):
2095 return result
2096 else:
2097 raise exc
2098
2099 def __iter__(cls):
2100 return (cls._member_map_[name] for name in cls._member_names_)
2101
2102 def __reversed__(cls):
2103 return (cls._member_map_[name] for name in reversed(cls._member_names_))
2104
2105 def __len__(cls):
2106 return len(cls._member_names_)
2107
2108 __nonzero__ = __bool__
2109
2110 def __repr__(cls):
2111 return "<aenum %r>" % (cls.__name__, )
2112
2113 def __setattr__(cls, name, value):
2114 """Block attempts to reassign Enum members/constants.
2115
2116 A simple assignment to the class namespace only changes one of the
2117 several possible ways to get an Enum member from the Enum class,
2118 resulting in an inconsistent Enumeration.
2119 """
2120 member_map = cls.__dict__.get('_member_map_', {})
2121 if name in member_map:
2122 raise AttributeError(
2123 '%s: cannot rebind member %r.' % (cls.__name__, name),
2124 )
2125 cur_obj = cls.__dict__.get(name)
2126 if isinstance(cur_obj, constant):
2127 raise AttributeError(
2128 '%s: cannot rebind constant %r' % (cls.__name__, name),
2129 )
2130 super(EnumMeta, cls).__setattr__(name, value)
2131
2132 def _create_(cls, class_name, names, module=None, type=None, start=1):
2133 """Convenience method to create a new Enum class.
2134
2135 `names` can be:
2136
2137 * A string containing member names, separated either with spaces or
2138 commas. Values are auto-numbered from 1.
2139 * An iterable of member names. Values are auto-numbered from 1.
2140 * An iterable of (member name, value) pairs.
2141 * A mapping of member name -> value.
2142 """
2143 if pyver < 3.0:
2144 # if class_name is unicode, attempt a conversion to ASCII
2145 if isinstance(class_name, unicode):
2146 try:
2147 class_name = class_name.encode('ascii')
2148 except UnicodeEncodeError:
2149 raise TypeError('%r is not representable in ASCII' % (class_name, ))
2150 metacls = cls.__class__
2151 if type is None:
2152 bases = (cls, )
2153 else:
2154 bases = (type, cls)
2155 _, first_enum = cls._get_mixins_(bases)
2156 generate = getattr(first_enum, '_generate_next_value_', None)
2157 generate = getattr(generate, 'im_func', generate)
2158 # special processing needed for names?
2159 if isinstance(names, basestring):
2160 names = names.replace(',', ' ').split()
2161 if isinstance(names, (tuple, list)) and names and isinstance(names[0], basestring):
2162 original_names, names = names, []
2163 last_values = []
2164 for count, name in enumerate(original_names):
2165 value = generate(name, start, count, last_values[:])
2166 last_values.append(value)
2167 names.append((name, value))
2168 # Here, names is either an iterable of (name, value) or a mapping.
2169 item = None # in case names is empty
2170 clsdict = None
2171 for item in names:
2172 if clsdict is None:
2173 # first time initialization
2174 if isinstance(item, basestring):
2175 clsdict = {}
2176 else:
2177 # remember the order
2178 clsdict = metacls.__prepare__(class_name, bases)
2179 if isinstance(item, basestring):
2180 member_name, member_value = item, names[item]
2181 else:
2182 member_name, member_value = item
2183 clsdict[member_name] = member_value
2184 if clsdict is None:
2185 # in case names was empty
2186 clsdict = metacls.__prepare__(class_name, bases)
2187 enum_class = metacls.__new__(metacls, class_name, bases, clsdict)
2188 # TODO: replace the frame hack if a blessed way to know the calling
2189 # module is ever developed
2190 if module is None:
2191 try:
2192 module = _sys._getframe(2).f_globals['__name__']
2193 except (AttributeError, KeyError):
2194 pass
2195 if module is None:
2196 _make_class_unpicklable(enum_class)
2197 else:
2198 enum_class.__module__ = module
2199 return enum_class
2200
2201 @staticmethod
2202 def _get_mixins_(bases):
2203 """Returns the type for creating enum members, and the first inherited
2204 enum class.
2205
2206 bases: the tuple of bases that was given to __new__
2207 """
2208 if not bases or Enum is None:
2209 return object, Enum
2210 def _find_data_type(bases):
2211 for chain in bases:
2212 for base in chain.__mro__:
2213 if base is object or base is StdlibEnum:
2214 continue
2215 elif '__new__' in base.__dict__:
2216 if issubclass(base, Enum):
2217 continue
2218 return base
2219
2220 # ensure final parent class is an Enum derivative, find any concrete
2221 # data type, and check that Enum has no members
2222 first_enum = bases[-1]
2223 if not issubclass(first_enum, Enum):
2224 raise TypeError("new enumerations should be created as "
2225 "`EnumName([mixin_type, ...] [data_type,] enum_type)`")
2226 member_type = _find_data_type(bases) or object
2227 if first_enum._member_names_:
2228 raise TypeError("cannot extend enumerations via subclassing")
2229
2230 return member_type, first_enum
2231
2232 if pyver < 3.0:
2233 @staticmethod
2234 def _find_new_(clsdict, member_type, first_enum):
2235 """Returns the __new__ to be used for creating the enum members.
2236
2237 clsdict: the class dictionary given to __new__
2238 member_type: the data type whose __new__ will be used by default
2239 first_enum: enumeration to check for an overriding __new__
2240 """
2241 # now find the correct __new__, checking to see of one was defined
2242 # by the user; also check earlier enum classes in case a __new__ was
2243 # saved as __new_member__
2244 __new__ = clsdict.get('__new__', None)
2245 if __new__:
2246 return None, True, True # __new__, save_new, new_uses_args
2247
2248 N__new__ = getattr(None, '__new__')
2249 O__new__ = getattr(object, '__new__')
2250 if Enum is None:
2251 E__new__ = N__new__
2252 else:
2253 E__new__ = Enum.__dict__['__new__']
2254 # check all possibles for __new_member__ before falling back to
2255 # __new__
2256 for method in ('__new_member__', '__new__'):
2257 for possible in (member_type, first_enum):
2258 try:
2259 target = possible.__dict__[method]
2260 except (AttributeError, KeyError):
2261 target = getattr(possible, method, None)
2262 if target not in [
2263 None,
2264 N__new__,
2265 O__new__,
2266 E__new__,
2267 ]:
2268 if method == '__new_member__':
2269 clsdict['__new__'] = target
2270 return None, False, True
2271 if isinstance(target, staticmethod):
2272 target = target.__get__(member_type)
2273 __new__ = target
2274 break
2275 if __new__ is not None:
2276 break
2277 else:
2278 __new__ = object.__new__
2279
2280 # if a non-object.__new__ is used then whatever value/tuple was
2281 # assigned to the enum member name will be passed to __new__ and to the
2282 # new enum member's __init__
2283 if __new__ is object.__new__:
2284 new_uses_args = False
2285 else:
2286 new_uses_args = True
2287
2288 return __new__, False, new_uses_args
2289 else:
2290 @staticmethod
2291 def _find_new_(clsdict, member_type, first_enum):
2292 """Returns the __new__ to be used for creating the enum members.
2293
2294 clsdict: the class dictionary given to __new__
2295 member_type: the data type whose __new__ will be used by default
2296 first_enum: enumeration to check for an overriding __new__
2297 """
2298 # now find the correct __new__, checking to see of one was defined
2299 # by the user; also check earlier enum classes in case a __new__ was
2300 # saved as __new_member__
2301 __new__ = clsdict.get('__new__', None)
2302
2303 # should __new__ be saved as __new_member__ later?
2304 save_new = __new__ is not None
2305
2306 if __new__ is None:
2307 # check all possibles for __new_member__ before falling back to
2308 # __new__
2309 for method in ('__new_member__', '__new__'):
2310 for possible in (member_type, first_enum):
2311 target = getattr(possible, method, None)
2312 if target not in (
2313 None,
2314 None.__new__,
2315 object.__new__,
2316 Enum.__new__,
2317 StdlibEnum.__new__
2318 ):
2319 __new__ = target
2320 break
2321 if __new__ is not None:
2322 break
2323 else:
2324 __new__ = object.__new__
2325 # if a non-object.__new__ is used then whatever value/tuple was
2326 # assigned to the enum member name will be passed to __new__ and to the
2327 # new enum member's __init__
2328 if __new__ is object.__new__:
2329 new_uses_args = False
2330 else:
2331 new_uses_args = True
2332
2333 return __new__, save_new, new_uses_args
2334
2335
2336 ########################################################
2337 # In order to support Python 2 and 3 with a single
2338 # codebase we have to create the Enum methods separately
2339 # and then use the `type(name, bases, dict)` method to
2340 # create the class.
2341 ########################################################
2342 temp_enum_dict = EnumMeta.__prepare__('Enum', (object, ))
2343 temp_enum_dict['__doc__'] = "Generic enumeration.\n\n Derive from this class to define new enumerations.\n\n"
2344
2345 def __init__(self, *args, **kwds):
2346 # auto-init method
2347 _auto_init_ = self._auto_init_
2348 if _auto_init_ is None:
2349 return
2350 if 'value' in _auto_init_:
2351 # remove 'value' from _auto_init_ as it has already been handled
2352 _auto_init_ = _auto_init_[1:]
2353 if _auto_init_:
2354 if len(_auto_init_) < len(args):
2355 raise TypeError('%d arguments expected (%s), %d received (%s)'
2356 % (len(_auto_init_), _auto_init_, len(args), args))
2357 for name, arg in zip(_auto_init_, args):
2358 setattr(self, name, arg)
2359 if len(args) < len(_auto_init_):
2360 remaining_args = _auto_init_[len(args):]
2361 for name in remaining_args:
2362 value = kwds.pop(name, undefined)
2363 if value is undefined:
2364 raise TypeError('missing value for: %r' % (name, ))
2365 setattr(self, name, value)
2366 if kwds:
2367 # too many keyword arguments
2368 raise TypeError('invalid keyword(s): %s' % ', '.join(kwds.keys()))
2369 temp_enum_dict['__init__'] = __init__
2370 del __init__
2371
2372 def __new__(cls, value):
2373 # all enum instances are actually created during class construction
2374 # without calling this method; this method is called by the metaclass'
2375 # __call__ (i.e. Color(3) ), and by pickle
2376 if NoAlias in cls._settings_:
2377 raise TypeError('NoAlias enumerations cannot be looked up by value')
2378 if type(value) is cls:
2379 # For lookups like Color(Color.red)
2380 # value = value.value
2381 return value
2382 # by-value search for a matching enum member
2383 # see if it's in the reverse mapping (for hashable values)
2384 try:
2385 if value in cls._value2member_map_:
2386 return cls._value2member_map_[value]
2387 except TypeError:
2388 # not there, now do long search -- O(n) behavior
2389 for name, member in cls._value2member_seq_:
2390 if name == value:
2391 return member
2392 # still not found -- try _missing_ hook
2393 try:
2394 exc = None
2395 result = cls._missing_value_(value)
2396 except Exception as e:
2397 exc = e
2398 result = None
2399 if isinstance(result, cls):
2400 return result
2401 else:
2402 if value is no_arg:
2403 ve_exc = ValueError('%s() should be called with a value' % (cls.__name__, ))
2404 else:
2405 ve_exc = ValueError("%r is not a valid %s" % (value, cls.__name__))
2406 if result is None and exc is None:
2407 raise ve_exc
2408 elif exc is None:
2409 exc = TypeError(
2410 'error in %s._missing_: returned %r instead of None or a valid member'
2411 % (cls.__name__, result)
2412 )
2413 exc.__context__ = ve_exc
2414 raise exc
2415 temp_enum_dict['__new__'] = __new__
2416 del __new__
2417
2418 @staticmethod
2419 def _generate_next_value_(name, start, count, last_values, *args, **kwds):
2420 for last_value in reversed(last_values):
2421 try:
2422 return last_value + 1
2423 except TypeError:
2424 pass
2425 else:
2426 return start
2427 temp_enum_dict['_generate_next_value_'] = _generate_next_value_
2428 del _generate_next_value_
2429
2430 @classmethod
2431 def _missing_(cls, value):
2432 "deprecated, use _missing_value_ instead"
2433 return None
2434 temp_enum_dict['_missing_'] = _missing_
2435 del _missing_
2436
2437 @classmethod
2438 def _missing_value_(cls, value):
2439 "used for failed value access"
2440 return cls._missing_(value)
2441 temp_enum_dict['_missing_value_'] = _missing_value_
2442 del _missing_value_
2443
2444 @classmethod
2445 def _missing_name_(cls, name):
2446 "used for failed item access"
2447 return None
2448 temp_enum_dict['_missing_name_'] = _missing_name_
2449 del _missing_name_
2450
2451 def __repr__(self):
2452 return "<%s.%s: %r>" % (
2453 self.__class__.__name__, self._name_, self._value_)
2454 temp_enum_dict['__repr__'] = __repr__
2455 del __repr__
2456
2457 def __str__(self):
2458 return "%s.%s" % (self.__class__.__name__, self._name_)
2459 temp_enum_dict['__str__'] = __str__
2460 del __str__
2461
2462 if pyver >= 3.0:
2463 def __dir__(self):
2464 added_behavior = [
2465 m
2466 for cls in self.__class__.mro()
2467 for m in cls.__dict__
2468 if m[0] != '_' and m not in self._member_map_
2469 ]
2470 return (['__class__', '__doc__', '__module__', ] + added_behavior)
2471 temp_enum_dict['__dir__'] = __dir__
2472 del __dir__
2473
2474 def __format__(self, format_spec):
2475 # mixed-in Enums should use the mixed-in type's __format__, otherwise
2476 # we can get strange results with the Enum name showing up instead of
2477 # the value
2478
2479 # pure Enum branch / overridden __str__ branch
2480 overridden_str = self.__class__.__str__ != Enum.__str__
2481 if self._member_type_ is object or overridden_str:
2482 cls = str
2483 val = str(self)
2484 # mix-in branch
2485 else:
2486 cls = self._member_type_
2487 val = self.value
2488 return cls.__format__(val, format_spec)
2489 temp_enum_dict['__format__'] = __format__
2490 del __format__
2491
2492 def __hash__(self):
2493 return hash(self._name_)
2494 temp_enum_dict['__hash__'] = __hash__
2495 del __hash__
2496
2497 def __reduce_ex__(self, proto):
2498 return self.__class__, (self._value_, )
2499 temp_enum_dict['__reduce_ex__'] = __reduce_ex__
2500 del __reduce_ex__
2501
2502
2503 ####################################
2504 # Python's less than 2.6 use __cmp__
2505
2506 if pyver < 2.6:
2507
2508 def __cmp__(self, other):
2509 if type(other) is self.__class__:
2510 if self is other:
2511 return 0
2512 return -1
2513 return NotImplemented
2514 raise TypeError("unorderable types: %s() and %s()" % (self.__class__.__name__, other.__class__.__name__))
2515 temp_enum_dict['__cmp__'] = __cmp__
2516 del __cmp__
2517
2518 else:
2519
2520 def __le__(self, other):
2521 raise TypeError("unorderable types: %s() <= %s()" % (self.__class__.__name__, other.__class__.__name__))
2522 temp_enum_dict['__le__'] = __le__
2523 del __le__
2524
2525 def __lt__(self, other):
2526 raise TypeError("unorderable types: %s() < %s()" % (self.__class__.__name__, other.__class__.__name__))
2527 temp_enum_dict['__lt__'] = __lt__
2528 del __lt__
2529
2530 def __ge__(self, other):
2531 raise TypeError("unorderable types: %s() >= %s()" % (self.__class__.__name__, other.__class__.__name__))
2532 temp_enum_dict['__ge__'] = __ge__
2533 del __ge__
2534
2535 def __gt__(self, other):
2536 raise TypeError("unorderable types: %s() > %s()" % (self.__class__.__name__, other.__class__.__name__))
2537 temp_enum_dict['__gt__'] = __gt__
2538 del __gt__
2539
2540
2541 def __eq__(self, other):
2542 if type(other) is self.__class__:
2543 return self is other
2544 return NotImplemented
2545 temp_enum_dict['__eq__'] = __eq__
2546 del __eq__
2547
2548 def __ne__(self, other):
2549 if type(other) is self.__class__:
2550 return self is not other
2551 return NotImplemented
2552 temp_enum_dict['__ne__'] = __ne__
2553 del __ne__
2554
2555 def __hash__(self):
2556 return hash(self._name_)
2557 temp_enum_dict['__hash__'] = __hash__
2558 del __hash__
2559
2560 def __reduce_ex__(self, proto):
2561 return self.__class__, (self._value_, )
2562 temp_enum_dict['__reduce_ex__'] = __reduce_ex__
2563 del __reduce_ex__
2564
2565 def _convert(cls, name, module, filter, source=None):
2566 """
2567 Create a new Enum subclass that replaces a collection of global constants
2568 """
2569 # convert all constants from source (or module) that pass filter() to
2570 # a new Enum called name, and export the enum and its members back to
2571 # module;
2572 # also, replace the __reduce_ex__ method so unpickling works in
2573 # previous Python versions
2574 module_globals = vars(_sys.modules[module])
2575 if source:
2576 source = vars(source)
2577 else:
2578 source = module_globals
2579 members = [(key, source[key]) for key in source.keys() if filter(key)]
2580 try:
2581 # sort by value, name
2582 members.sort(key=lambda t: (t[1], t[0]))
2583 except TypeError:
2584 # unless some values aren't comparable, in which case sort by just name
2585 members.sort(key=lambda t: t[0])
2586 cls = cls(name, members, module=module)
2587 cls.__reduce_ex__ = _reduce_ex_by_name
2588 module_globals.update(cls.__members__)
2589 module_globals[name] = cls
2590 return cls
2591 temp_enum_dict['_convert'] = classmethod(_convert)
2592 del _convert
2593
2594 # enum_property is used to provide access to the `name`, `value', etc.,
2595 # properties of enum members while keeping some measure of protection
2596 # from modification, while still allowing for an enumeration to have
2597 # members named `name`, `value`, etc.. This works because enumeration
2598 # members are not set directly on the enum class -- enum_property will
2599 # look them up in _member_map_.
2600 #
2601 # This method is also very slow, so EnumMeta will add members directlyi
2602 # to the Enum class if it won't shadow other instance attributes
2603
2604 @enum_property
2605 def name(self):
2606 return self._name_
2607 temp_enum_dict['name'] = name
2608 del name
2609
2610 @enum_property
2611 def value(self):
2612 return self._value_
2613 temp_enum_dict['value'] = value
2614 del value
2615
2616 @enum_property
2617 def values(self):
2618 return self._values_
2619 temp_enum_dict['values'] = values
2620 del values
2621
2622 def _reduce_ex_by_name(self, proto):
2623 return self.name
2624
2625 if StdlibEnum is not None:
2626 Enum = EnumMeta('Enum', (StdlibEnum, ), temp_enum_dict)
2627 else:
2628 Enum = EnumMeta('Enum', (object, ), temp_enum_dict)
2629 del temp_enum_dict
2630
2631 # Enum has now been created
2632 ###########################
2633
2634 class IntEnum(int, Enum):
2635 """Enum where members are also (and must be) ints"""
2636
2637 if pyver >= 3:
2638 class AutoEnum(Enum):
2639 """
2640 automatically use _generate_next_value_ when values are missing (Python 3 only)
2641 """
2642 _settings_ = AutoValue
2643
2644 class AutoNumberEnum(Enum):
2645 """
2646 Automatically assign increasing values to members.
2647
2648 Py3: numbers match creation order
2649 Py2: numbers are assigned alphabetically by member name
2650 """
2651 def __new__(cls, *args, **kwds):
2652 value = len(cls.__members__) + 1
2653 obj = object.__new__(cls)
2654 obj._value_ = value
2655 return obj
2656
2657 class MultiValueEnum(Enum):
2658 """
2659 Multiple values can map to each member.
2660 """
2661 _settings_ = MultiValue
2662
2663 class NoAliasEnum(Enum):
2664 """
2665 Duplicate value members are distinct, and cannot be looked up by value.
2666 """
2667 _settings_ = NoAlias
2668
2669 class OrderedEnum(Enum):
2670 """
2671 Add ordering based on values of Enum members.
2672 """
2673 def __ge__(self, other):
2674 if self.__class__ is other.__class__:
2675 return self._value_ >= other._value_
2676 return NotImplemented
2677
2678 def __gt__(self, other):
2679 if self.__class__ is other.__class__:
2680 return self._value_ > other._value_
2681 return NotImplemented
2682
2683 def __le__(self, other):
2684 if self.__class__ is other.__class__:
2685 return self._value_ <= other._value_
2686 return NotImplemented
2687
2688 def __lt__(self, other):
2689 if self.__class__ is other.__class__:
2690 return self._value_ < other._value_
2691 return NotImplemented
2692
2693 if sqlite3:
2694 class SqliteEnum(Enum):
2695 def __conform__(self, protocol):
2696 if protocol is sqlite3.PrepareProtocol:
2697 return self.name
2698
2699 class UniqueEnum(Enum):
2700 """
2701 Ensure no duplicate values exist.
2702 """
2703 _settings_ = Unique
2704
2705
2706 def convert(enum, name, module, filter, source=None):
2707 """
2708 Create a new Enum subclass that replaces a collection of global constants
2709
2710 enum: Enum, IntEnum, ...
2711 name: name of new Enum
2712 module: name of module (__name__ in global context)
2713 filter: function that returns True if name should be converted to Enum member
2714 source: namespace to check (defaults to 'module')
2715 """
2716 # convert all constants from source (or module) that pass filter() to
2717 # a new Enum called name, and export the enum and its members back to
2718 # module;
2719 # also, replace the __reduce_ex__ method so unpickling works in
2720 # previous Python versions
2721 module_globals = vars(_sys.modules[module])
2722 if source:
2723 source = vars(source)
2724 else:
2725 source = module_globals
2726 members = dict((name, value) for name, value in source.items() if filter(name))
2727 enum = enum(name, members, module=module)
2728 enum.__reduce_ex__ = _reduce_ex_by_name
2729 module_globals.update(enum.__members__)
2730 module_globals[name] = enum
2731
2732 def extend_enum(enumeration, name, *args, **_private_kwds):
2733 """
2734 Add a new member to an existing Enum.
2735 """
2736 try:
2737 _member_map_ = enumeration._member_map_
2738 _member_names_ = enumeration._member_names_
2739 _member_type_ = enumeration._member_type_
2740 _value2member_map_ = enumeration._value2member_map_
2741 base_attributes = set([a for b in enumeration.mro() for a in b.__dict__])
2742 except AttributeError:
2743 raise TypeError('%r is not a supported Enum' % (enumeration, ))
2744 try:
2745 _value2member_seq_ = enumeration._value2member_seq_
2746 # _auto_number_ = enumeration._auto_number_
2747 _multi_value_ = MultiValue in enumeration._settings_
2748 _no_alias_ = NoAlias in enumeration._settings_
2749 _unique_ = Unique in enumeration._settings_
2750 # _unique_ = Unique in enumeration._settings_
2751 _auto_init_ = enumeration._auto_init_ or []
2752 except AttributeError:
2753 # standard Enum
2754 _value2member_seq_ = []
2755 # _auto_number_ = False
2756 _multi_value_ = False
2757 _no_alias_ = False
2758 # _unique_ = False
2759 _auto_init_ = []
2760 mt_new = _member_type_.__new__
2761 _new = getattr(enumeration, '__new_member__', mt_new)
2762 if not args:
2763 _gnv = getattr(enumeration, '_generate_next_value_')
2764 if _gnv is None:
2765 raise TypeError('value not provided and _generate_next_value_ missing')
2766 last_values = [m.value for m in enumeration]
2767 count = len(enumeration)
2768 start = getattr(enumeration, '_start_')
2769 if start is None:
2770 start = last_values and last_values[0] or 1
2771 args = ( _gnv(name, start, count, last_values), )
2772 if _new is object.__new__:
2773 new_uses_args = False
2774 else:
2775 new_uses_args = True
2776 if len(args) == 1:
2777 [value] = args
2778 else:
2779 value = args
2780 more_values = ()
2781 kwds = {}
2782 if isinstance(value, enum):
2783 args = value.args
2784 kwds = value.kwds
2785 if not isinstance(value, tuple):
2786 args = (value, )
2787 else:
2788 args = value
2789 # tease value out of auto-init if specified
2790 if 'value' in _auto_init_:
2791 if 'value' in kwds:
2792 value = kwds.pop('value')
2793 else:
2794 value, args = args[0], args[1:]
2795 elif _multi_value_:
2796 value, more_values, args = args[0], args[1:], ()
2797 if _member_type_ is tuple:
2798 args = (args, )
2799 if not new_uses_args:
2800 new_member = _new(enumeration)
2801 if not hasattr(new_member, '_value_'):
2802 new_member._value_ = value
2803 else:
2804 new_member = _new(enumeration, *args, **kwds)
2805 if not hasattr(new_member, '_value_'):
2806 new_member._value_ = _member_type_(*args)
2807 value = new_member._value_
2808 new_member._name_ = name
2809 new_member.__objclass__ = enumeration.__class__
2810 new_member.__init__(*args)
2811 if _private_kwds.get('create_only'):
2812 return new_member
2813 # If another member with the same value was already defined, the
2814 # new member becomes an alias to the existing one.
2815 is_alias = False
2816 if _no_alias_:
2817 # unless NoAlias was specified
2818 _member_names_.append(name)
2819 _member_map_[name] = new_member
2820 else:
2821 for canonical_member in _member_map_.values():
2822 _values_ = getattr(canonical_member, '_values_', [canonical_member._value_])
2823 for canonical_value in _values_:
2824 if canonical_value == new_member._value_:
2825 # name is an alias
2826 if _unique_ or _multi_value_:
2827 # aliases not allowed if Unique specified
2828 raise ValueError('%s is a duplicate of %s' % (name, canonical_member.name))
2829 if name not in base_attributes:
2830 setattr(enumeration, name, canonical_member)
2831 else:
2832 # check type of name
2833 for parent in enumeration.mro()[1:]:
2834 if name in parent.__dict__:
2835 obj = parent.__dict__[name]
2836 if not isinstance(obj, enum_property):
2837 raise TypeError('%r already used: %r' % (name, obj))
2838 break
2839 # Aliases don't appear in member names (only in __members__ and _member_map_).
2840 _member_map_[new_member._name_] = canonical_member
2841 new_member = canonical_member
2842 is_alias = True
2843 break
2844 if is_alias:
2845 break
2846 else:
2847 # not an alias
2848 values = (value, ) + more_values
2849 new_member._values_ = values
2850 for value in (value, ) + more_values:
2851 # first check if value has already been used
2852 if _multi_value_ and (
2853 value in _value2member_map_
2854 or any(v == value for (v, m) in _value2member_seq_)
2855 ):
2856 raise ValueError('%r has already been used' % (value, ))
2857 try:
2858 # This may fail if value is not hashable. We can't add the value
2859 # to the map, and by-value lookups for this value will be
2860 # linear.
2861 if _no_alias_:
2862 raise TypeError('cannot use dict to store value')
2863 _value2member_map_[value] = new_member
2864 except TypeError:
2865 _value2member_seq_ += ((value, new_member), )
2866 if name not in base_attributes:
2867 setattr(enumeration, name, new_member)
2868 else:
2869 # check type of name
2870 for parent in enumeration.mro()[1:]:
2871 if name in parent.__dict__:
2872 obj = parent.__dict__[name]
2873 if not isinstance(obj, enum_property):
2874 raise TypeError('%r already used: %r' % (name, obj))
2875 break
2876 _member_names_.append(name)
2877 _member_map_[name] = new_member
2878 try:
2879 _value2member_map_[value] = new_member
2880 except TypeError:
2881 pass
2882
2883 def unique(enumeration):
2884 """
2885 Class decorator that ensures only unique members exist in an enumeration.
2886 """
2887 duplicates = []
2888 for name, member in enumeration.__members__.items():
2889 if name != member.name:
2890 duplicates.append((name, member.name))
2891 if duplicates:
2892 duplicate_names = ', '.join(
2893 ["%s -> %s" % (alias, name) for (alias, name) in duplicates]
2894 )
2895 raise ValueError('duplicate names found in %r: %s' %
2896 (enumeration, duplicate_names)
2897 )
2898 return enumeration
2899
2900 class Flag(Enum):
2901 """Support for flags"""
2902
2903 def _generate_next_value_(name, start, count, last_values):
2904 """
2905 Generate the next value when not given.
2906
2907 name: the name of the member
2908 start: the initital start value or None
2909 count: the number of existing members
2910 last_value: the last value assigned or None
2911 """
2912 if not count:
2913 return (1, start)[start is not None]
2914 error = False
2915 for last_value in reversed(last_values):
2916 if isinstance(last_value, auto):
2917 last_value = last_value.value
2918 try:
2919 high_bit = _high_bit(last_value)
2920 break
2921 except Exception:
2922 error = True
2923 break
2924 if error:
2925 raise TypeError('invalid Flag value: %r' % (last_value, ))
2926 return 2 ** (high_bit+1)
2927
2928 @classmethod
2929 def _missing_(cls, value):
2930 original_value = value
2931 if value < 0:
2932 value = ~value
2933 possible_member = cls._create_pseudo_member_(value)
2934 if original_value < 0:
2935 possible_member = ~possible_member
2936 return possible_member
2937
2938 @classmethod
2939 def _create_pseudo_member_(cls, *values):
2940 """
2941 Create a composite member iff value contains only members.
2942 """
2943 value = values[0]
2944 pseudo_member = cls._value2member_map_.get(value, None)
2945 if pseudo_member is None:
2946 # verify all bits are accounted for
2947 members, extra_flags = _decompose(cls, value)
2948 if extra_flags:
2949 raise ValueError("%r is not a valid %s" % (value, cls.__name__))
2950 # give subclasses a chance to modify values for new pseudo-member
2951 values = cls._create_pseudo_member_values_(members, *values)
2952 # construct a singleton enum pseudo-member
2953 pseudo_member = extend_enum(cls, None, *values, create_only=True)
2954 # use setdefault in case another thread already created a composite
2955 # with this value
2956 pseudo_member = cls._value2member_map_.setdefault(value, pseudo_member)
2957 return pseudo_member
2958
2959 @classmethod
2960 def _create_pseudo_member_values_(cls, members, *values):
2961 return values
2962
2963 def __contains__(self, other):
2964 if not isinstance(other, Flag):
2965 raise TypeError("%r (%r) is not an <aenum 'Flag'>" % (other, type(other)))
2966 if not isinstance(other, self.__class__):
2967 return False
2968 return other._value_ & self._value_ == other._value_
2969
2970 def __repr__(self):
2971 cls = self.__class__
2972 if self._name_ is not None:
2973 return '<%s.%s: %r>' % (cls.__name__, self._name_, self._value_)
2974 members, uncovered = _decompose(cls, self._value_)
2975 return '<%s.%s: %r>' % (
2976 cls.__name__,
2977 '|'.join([str(m._name_ or m._value_) for m in members]),
2978 self._value_,
2979 )
2980
2981 def __str__(self):
2982 cls = self.__class__
2983 if self._name_ is not None:
2984 return '%s.%s' % (cls.__name__, self._name_)
2985 members, uncovered = _decompose(cls, self._value_)
2986 if len(members) == 1 and members[0]._name_ is None:
2987 return '%s.%r' % (cls.__name__, members[0]._value_)
2988 else:
2989 return '%s.%s' % (
2990 cls.__name__,
2991 '|'.join([str(m._name_ or m._value_) for m in members]),
2992 )
2993
2994 def __bool__(self):
2995 return bool(self._value_)
2996 if pyver < 3:
2997 __nonzero__ = __bool__
2998 del __bool__
2999
3000 def __or__(self, other):
3001 if not isinstance(other, self.__class__):
3002 return NotImplemented
3003 return self.__class__(self._value_ | other._value_)
3004
3005 def __and__(self, other):
3006 if not isinstance(other, self.__class__):
3007 return NotImplemented
3008 return self.__class__(self._value_ & other._value_)
3009
3010 def __xor__(self, other):
3011 if not isinstance(other, self.__class__):
3012 return NotImplemented
3013 return self.__class__(self._value_ ^ other._value_)
3014
3015 def __invert__(self):
3016 members, uncovered = _decompose(self.__class__, self._value_)
3017 inverted_members = [
3018 m for m in self.__class__
3019 if m not in members and not m._value_ & self._value_
3020 ]
3021 inverted = reduce(_or_, inverted_members, self.__class__(0))
3022 return self.__class__(inverted)
3023
3024 def __iter__(self):
3025 members, extra_flags = _decompose(self.__class__, self.value)
3026 return (m for m in members if m._value_ != 0)
3027
3028
3029 class IntFlag(int, Flag):
3030 """Support for integer-based Flags"""
3031
3032 @classmethod
3033 def _missing_(cls, value):
3034 if not isinstance(value, int):
3035 raise ValueError("%r is not a valid %s" % (value, cls.__name__))
3036 new_member = cls._create_pseudo_member_(value)
3037 return new_member
3038
3039 @classmethod
3040 def _create_pseudo_member_(cls, value):
3041 pseudo_member = cls._value2member_map_.get(value, None)
3042 if pseudo_member is None:
3043 need_to_create = [value]
3044 # get unaccounted for bits
3045 _, extra_flags = _decompose(cls, value)
3046 while extra_flags:
3047 bit = _high_bit(extra_flags)
3048 flag_value = 2 ** bit
3049 if (flag_value not in cls._value2member_map_ and
3050 flag_value not in need_to_create
3051 ):
3052 need_to_create.append(flag_value)
3053 if extra_flags == -flag_value:
3054 extra_flags = 0
3055 else:
3056 extra_flags ^= flag_value
3057 for value in reversed(need_to_create):
3058 # construct singleton pseudo-members
3059 pseudo_member = int.__new__(cls, value)
3060 pseudo_member._name_ = None
3061 pseudo_member._value_ = value
3062 # use setdefault in case another thread already created a composite
3063 # with this value
3064 pseudo_member = cls._value2member_map_.setdefault(value, pseudo_member)
3065 return pseudo_member
3066
3067 def __or__(self, other):
3068 if not isinstance(other, (self.__class__, int)):
3069 return NotImplemented
3070 result = self.__class__(self._value_ | self.__class__(other)._value_)
3071 return result
3072
3073 def __and__(self, other):
3074 if not isinstance(other, (self.__class__, int)):
3075 return NotImplemented
3076 return self.__class__(self._value_ & self.__class__(other)._value_)
3077
3078 def __xor__(self, other):
3079 if not isinstance(other, (self.__class__, int)):
3080 return NotImplemented
3081 return self.__class__(self._value_ ^ self.__class__(other)._value_)
3082
3083 __ror__ = __or__
3084 __rand__ = __and__
3085 __rxor__ = __xor__
3086
3087 def __invert__(self):
3088 result = self.__class__(~self._value_)
3089 return result
3090
3091
3092 def _high_bit(value):
3093 """returns index of highest bit, or -1 if value is zero or negative"""
3094 return value.bit_length() - 1
3095
3096 def _decompose(flag, value):
3097 """Extract all members from the value."""
3098 # _decompose is only called if the value is not named
3099 not_covered = value
3100 negative = value < 0
3101 # issue29167: wrap accesses to _value2member_map_ in a list to avoid race
3102 # conditions between iterating over it and having more psuedo-
3103 # members added to it
3104 if negative:
3105 # only check for named flags
3106 flags_to_check = [
3107 (m, v)
3108 for v, m in list(flag._value2member_map_.items())
3109 if m.name is not None
3110 ]
3111 else:
3112 # check for named flags and powers-of-two flags
3113 flags_to_check = [
3114 (m, v)
3115 for v, m in list(flag._value2member_map_.items())
3116 if m.name is not None or _power_of_two(v)
3117 ]
3118 members = []
3119 for member, member_value in flags_to_check:
3120 if member_value and member_value & value == member_value:
3121 members.append(member)
3122 not_covered &= ~member_value
3123 if not members and value in flag._value2member_map_:
3124 members.append(flag._value2member_map_[value])
3125 members.sort(key=lambda m: m._value_, reverse=True)
3126 if len(members) > 1 and members[0].value == value:
3127 # we have the breakdown, don't need the value member itself
3128 members.pop(0)
3129 return members, not_covered
3130
3131 def _power_of_two(value):
3132 if value < 1:
3133 return False
3134 return value == 2 ** _high_bit(value)
3135
3136
3137 class module(object):
3138
3139 def __init__(self, cls, *args):
3140 self.__name__ = cls.__name__
3141 self._parent_module = cls.__module__
3142 self.__all__ = []
3143 all_objects = cls.__dict__
3144 if not args:
3145 args = [k for k, v in all_objects.items() if isinstance(v, (NamedConstant, Enum))]
3146 for name in args:
3147 self.__dict__[name] = all_objects[name]
3148 self.__all__.append(name)
3149
3150 def register(self):
3151 _sys.modules["%s.%s" % (self._parent_module, self.__name__)] = self
3152
3153