comparison planemo/lib/python3.7/site-packages/aenum/__init__.py @ 0:d30785e31577 draft

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