1# pylint: skip-file 2# vendored from: 3# https://bitbucket.org/stoneleaf/enum34/src/58c4cd7174ca35f164304c8a6f0a4d47b779c2a7/enum/__init__.py?at=1.1.6 4 5"""Python Enumerations""" 6 7import sys as _sys 8 9__all__ = ['Enum', 'IntEnum', 'unique'] 10 11version = 1, 1, 6 12 13pyver = float('%s.%s' % _sys.version_info[:2]) 14 15try: 16 any 17except NameError: 18 def any(iterable): 19 for element in iterable: 20 if element: 21 return True 22 return False 23 24try: 25 from collections import OrderedDict 26except ImportError: 27 OrderedDict = None 28 29try: 30 basestring 31except NameError: 32 # In Python 2 basestring is the ancestor of both str and unicode 33 # in Python 3 it's just str, but was missing in 3.1 34 basestring = str 35 36try: 37 unicode 38except NameError: 39 # In Python 3 unicode no longer exists (it's just str) 40 unicode = str 41 42class _RouteClassAttributeToGetattr(object): 43 """Route attribute access on a class to __getattr__. 44 45 This is a descriptor, used to define attributes that act differently when 46 accessed through an instance and through a class. Instance access remains 47 normal, but access to an attribute through a class will be routed to the 48 class's __getattr__ method; this is done by raising AttributeError. 49 50 """ 51 def __init__(self, fget=None): 52 self.fget = fget 53 54 def __get__(self, instance, ownerclass=None): 55 if instance is None: 56 raise AttributeError() 57 return self.fget(instance) 58 59 def __set__(self, instance, value): 60 raise AttributeError("can't set attribute") 61 62 def __delete__(self, instance): 63 raise AttributeError("can't delete attribute") 64 65 66def _is_descriptor(obj): 67 """Returns True if obj is a descriptor, False otherwise.""" 68 return ( 69 hasattr(obj, '__get__') or 70 hasattr(obj, '__set__') or 71 hasattr(obj, '__delete__')) 72 73 74def _is_dunder(name): 75 """Returns True if a __dunder__ name, False otherwise.""" 76 return (name[:2] == name[-2:] == '__' and 77 name[2:3] != '_' and 78 name[-3:-2] != '_' and 79 len(name) > 4) 80 81 82def _is_sunder(name): 83 """Returns True if a _sunder_ name, False otherwise.""" 84 return (name[0] == name[-1] == '_' and 85 name[1:2] != '_' and 86 name[-2:-1] != '_' and 87 len(name) > 2) 88 89 90def _make_class_unpicklable(cls): 91 """Make the given class un-picklable.""" 92 def _break_on_call_reduce(self, protocol=None): 93 raise TypeError('%r cannot be pickled' % self) 94 cls.__reduce_ex__ = _break_on_call_reduce 95 cls.__module__ = '<unknown>' 96 97 98class _EnumDict(dict): 99 """Track enum member order and ensure member names are not reused. 100 101 EnumMeta will use the names found in self._member_names as the 102 enumeration member names. 103 104 """ 105 def __init__(self): 106 super(_EnumDict, self).__init__() 107 self._member_names = [] 108 109 def __setitem__(self, key, value): 110 """Changes anything not dundered or not a descriptor. 111 112 If a descriptor is added with the same name as an enum member, the name 113 is removed from _member_names (this may leave a hole in the numerical 114 sequence of values). 115 116 If an enum member name is used twice, an error is raised; duplicate 117 values are not checked for. 118 119 Single underscore (sunder) names are reserved. 120 121 Note: in 3.x __order__ is simply discarded as a not necessary piece 122 leftover from 2.x 123 124 """ 125 if pyver >= 3.0 and key in ('_order_', '__order__'): 126 return 127 elif key == '__order__': 128 key = '_order_' 129 if _is_sunder(key): 130 if key != '_order_': 131 raise ValueError('_names_ are reserved for future Enum use') 132 elif _is_dunder(key): 133 pass 134 elif key in self._member_names: 135 # descriptor overwriting an enum? 136 raise TypeError('Attempted to reuse key: %r' % key) 137 elif not _is_descriptor(value): 138 if key in self: 139 # enum overwriting a descriptor? 140 raise TypeError('Key already defined as: %r' % self[key]) 141 self._member_names.append(key) 142 super(_EnumDict, self).__setitem__(key, value) 143 144 145# Dummy value for Enum as EnumMeta explicity checks for it, but of course until 146# EnumMeta finishes running the first time the Enum class doesn't exist. This 147# is also why there are checks in EnumMeta like `if Enum is not None` 148Enum = None 149 150 151class EnumMeta(type): 152 """Metaclass for Enum""" 153 @classmethod 154 def __prepare__(metacls, cls, bases): 155 return _EnumDict() 156 157 def __new__(metacls, cls, bases, classdict): 158 # an Enum class is final once enumeration items have been defined; it 159 # cannot be mixed with other types (int, float, etc.) if it has an 160 # inherited __new__ unless a new __new__ is defined (or the resulting 161 # class will fail). 162 if type(classdict) is dict: 163 original_dict = classdict 164 classdict = _EnumDict() 165 for k, v in original_dict.items(): 166 classdict[k] = v 167 168 member_type, first_enum = metacls._get_mixins_(bases) 169 __new__, save_new, use_args = metacls._find_new_(classdict, member_type, 170 first_enum) 171 # save enum items into separate mapping so they don't get baked into 172 # the new class 173 members = dict((k, classdict[k]) for k in classdict._member_names) 174 for name in classdict._member_names: 175 del classdict[name] 176 177 # py2 support for definition order 178 _order_ = classdict.get('_order_') 179 if _order_ is None: 180 if pyver < 3.0: 181 try: 182 _order_ = [name for (name, value) in sorted(members.items(), key=lambda item: item[1])] 183 except TypeError: 184 _order_ = [name for name in sorted(members.keys())] 185 else: 186 _order_ = classdict._member_names 187 else: 188 del classdict['_order_'] 189 if pyver < 3.0: 190 _order_ = _order_.replace(',', ' ').split() 191 aliases = [name for name in members if name not in _order_] 192 _order_ += aliases 193 194 # check for illegal enum names (any others?) 195 invalid_names = set(members) & set(['mro']) 196 if invalid_names: 197 raise ValueError('Invalid enum member name(s): %s' % ( 198 ', '.join(invalid_names), )) 199 200 # save attributes from super classes so we know if we can take 201 # the shortcut of storing members in the class dict 202 base_attributes = set([a for b in bases for a in b.__dict__]) 203 # create our new Enum type 204 enum_class = super(EnumMeta, metacls).__new__(metacls, cls, bases, classdict) 205 enum_class._member_names_ = [] # names in random order 206 if OrderedDict is not None: 207 enum_class._member_map_ = OrderedDict() 208 else: 209 enum_class._member_map_ = {} # name->value map 210 enum_class._member_type_ = member_type 211 212 # Reverse value->name map for hashable values. 213 enum_class._value2member_map_ = {} 214 215 # instantiate them, checking for duplicates as we go 216 # we instantiate first instead of checking for duplicates first in case 217 # a custom __new__ is doing something funky with the values -- such as 218 # auto-numbering ;) 219 if __new__ is None: 220 __new__ = enum_class.__new__ 221 for member_name in _order_: 222 value = members[member_name] 223 if not isinstance(value, tuple): 224 args = (value, ) 225 else: 226 args = value 227 if member_type is tuple: # special case for tuple enums 228 args = (args, ) # wrap it one more time 229 if not use_args or not args: 230 enum_member = __new__(enum_class) 231 if not hasattr(enum_member, '_value_'): 232 enum_member._value_ = value 233 else: 234 enum_member = __new__(enum_class, *args) 235 if not hasattr(enum_member, '_value_'): 236 enum_member._value_ = member_type(*args) 237 value = enum_member._value_ 238 enum_member._name_ = member_name 239 enum_member.__objclass__ = enum_class 240 enum_member.__init__(*args) 241 # If another member with the same value was already defined, the 242 # new member becomes an alias to the existing one. 243 for name, canonical_member in enum_class._member_map_.items(): 244 if canonical_member.value == enum_member._value_: 245 enum_member = canonical_member 246 break 247 else: 248 # Aliases don't appear in member names (only in __members__). 249 enum_class._member_names_.append(member_name) 250 # performance boost for any member that would not shadow 251 # a DynamicClassAttribute (aka _RouteClassAttributeToGetattr) 252 if member_name not in base_attributes: 253 setattr(enum_class, member_name, enum_member) 254 # now add to _member_map_ 255 enum_class._member_map_[member_name] = enum_member 256 try: 257 # This may fail if value is not hashable. We can't add the value 258 # to the map, and by-value lookups for this value will be 259 # linear. 260 enum_class._value2member_map_[value] = enum_member 261 except TypeError: 262 pass 263 264 265 # If a custom type is mixed into the Enum, and it does not know how 266 # to pickle itself, pickle.dumps will succeed but pickle.loads will 267 # fail. Rather than have the error show up later and possibly far 268 # from the source, sabotage the pickle protocol for this class so 269 # that pickle.dumps also fails. 270 # 271 # However, if the new class implements its own __reduce_ex__, do not 272 # sabotage -- it's on them to make sure it works correctly. We use 273 # __reduce_ex__ instead of any of the others as it is preferred by 274 # pickle over __reduce__, and it handles all pickle protocols. 275 unpicklable = False 276 if '__reduce_ex__' not in classdict: 277 if member_type is not object: 278 methods = ('__getnewargs_ex__', '__getnewargs__', 279 '__reduce_ex__', '__reduce__') 280 if not any(m in member_type.__dict__ for m in methods): 281 _make_class_unpicklable(enum_class) 282 unpicklable = True 283 284 285 # double check that repr and friends are not the mixin's or various 286 # things break (such as pickle) 287 for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'): 288 class_method = getattr(enum_class, name) 289 obj_method = getattr(member_type, name, None) 290 enum_method = getattr(first_enum, name, None) 291 if name not in classdict and class_method is not enum_method: 292 if name == '__reduce_ex__' and unpicklable: 293 continue 294 setattr(enum_class, name, enum_method) 295 296 # method resolution and int's are not playing nice 297 # Python's less than 2.6 use __cmp__ 298 299 if pyver < 2.6: 300 301 if issubclass(enum_class, int): 302 setattr(enum_class, '__cmp__', getattr(int, '__cmp__')) 303 304 elif pyver < 3.0: 305 306 if issubclass(enum_class, int): 307 for method in ( 308 '__le__', 309 '__lt__', 310 '__gt__', 311 '__ge__', 312 '__eq__', 313 '__ne__', 314 '__hash__', 315 ): 316 setattr(enum_class, method, getattr(int, method)) 317 318 # replace any other __new__ with our own (as long as Enum is not None, 319 # anyway) -- again, this is to support pickle 320 if Enum is not None: 321 # if the user defined their own __new__, save it before it gets 322 # clobbered in case they subclass later 323 if save_new: 324 setattr(enum_class, '__member_new__', enum_class.__dict__['__new__']) 325 setattr(enum_class, '__new__', Enum.__dict__['__new__']) 326 return enum_class 327 328 def __bool__(cls): 329 """ 330 classes/types should always be True. 331 """ 332 return True 333 334 def __call__(cls, value, names=None, module=None, type=None, start=1): 335 """Either returns an existing member, or creates a new enum class. 336 337 This method is used both when an enum class is given a value to match 338 to an enumeration member (i.e. Color(3)) and for the functional API 339 (i.e. Color = Enum('Color', names='red green blue')). 340 341 When used for the functional API: `module`, if set, will be stored in 342 the new class' __module__ attribute; `type`, if set, will be mixed in 343 as the first base class. 344 345 Note: if `module` is not set this routine will attempt to discover the 346 calling module by walking the frame stack; if this is unsuccessful 347 the resulting class will not be pickleable. 348 349 """ 350 if names is None: # simple value lookup 351 return cls.__new__(cls, value) 352 # otherwise, functional API: we're creating a new Enum type 353 return cls._create_(value, names, module=module, type=type, start=start) 354 355 def __contains__(cls, member): 356 return isinstance(member, cls) and member.name in cls._member_map_ 357 358 def __delattr__(cls, attr): 359 # nicer error message when someone tries to delete an attribute 360 # (see issue19025). 361 if attr in cls._member_map_: 362 raise AttributeError( 363 "%s: cannot delete Enum member." % cls.__name__) 364 super(EnumMeta, cls).__delattr__(attr) 365 366 def __dir__(self): 367 return (['__class__', '__doc__', '__members__', '__module__'] + 368 self._member_names_) 369 370 @property 371 def __members__(cls): 372 """Returns a mapping of member name->value. 373 374 This mapping lists all enum members, including aliases. Note that this 375 is a copy of the internal mapping. 376 377 """ 378 return cls._member_map_.copy() 379 380 def __getattr__(cls, name): 381 """Return the enum member matching `name` 382 383 We use __getattr__ instead of descriptors or inserting into the enum 384 class' __dict__ in order to support `name` and `value` being both 385 properties for enum members (which live in the class' __dict__) and 386 enum members themselves. 387 388 """ 389 if _is_dunder(name): 390 raise AttributeError(name) 391 try: 392 return cls._member_map_[name] 393 except KeyError: 394 raise AttributeError(name) 395 396 def __getitem__(cls, name): 397 return cls._member_map_[name] 398 399 def __iter__(cls): 400 return (cls._member_map_[name] for name in cls._member_names_) 401 402 def __reversed__(cls): 403 return (cls._member_map_[name] for name in reversed(cls._member_names_)) 404 405 def __len__(cls): 406 return len(cls._member_names_) 407 408 __nonzero__ = __bool__ 409 410 def __repr__(cls): 411 return "<enum %r>" % cls.__name__ 412 413 def __setattr__(cls, name, value): 414 """Block attempts to reassign Enum members. 415 416 A simple assignment to the class namespace only changes one of the 417 several possible ways to get an Enum member from the Enum class, 418 resulting in an inconsistent Enumeration. 419 420 """ 421 member_map = cls.__dict__.get('_member_map_', {}) 422 if name in member_map: 423 raise AttributeError('Cannot reassign members.') 424 super(EnumMeta, cls).__setattr__(name, value) 425 426 def _create_(cls, class_name, names=None, module=None, type=None, start=1): 427 """Convenience method to create a new Enum class. 428 429 `names` can be: 430 431 * A string containing member names, separated either with spaces or 432 commas. Values are auto-numbered from 1. 433 * An iterable of member names. Values are auto-numbered from 1. 434 * An iterable of (member name, value) pairs. 435 * A mapping of member name -> value. 436 437 """ 438 if pyver < 3.0: 439 # if class_name is unicode, attempt a conversion to ASCII 440 if isinstance(class_name, unicode): 441 try: 442 class_name = class_name.encode('ascii') 443 except UnicodeEncodeError: 444 raise TypeError('%r is not representable in ASCII' % class_name) 445 metacls = cls.__class__ 446 if type is None: 447 bases = (cls, ) 448 else: 449 bases = (type, cls) 450 classdict = metacls.__prepare__(class_name, bases) 451 _order_ = [] 452 453 # special processing needed for names? 454 if isinstance(names, basestring): 455 names = names.replace(',', ' ').split() 456 if isinstance(names, (tuple, list)) and isinstance(names[0], basestring): 457 names = [(e, i+start) for (i, e) in enumerate(names)] 458 459 # Here, names is either an iterable of (name, value) or a mapping. 460 item = None # in case names is empty 461 for item in names: 462 if isinstance(item, basestring): 463 member_name, member_value = item, names[item] 464 else: 465 member_name, member_value = item 466 classdict[member_name] = member_value 467 _order_.append(member_name) 468 # only set _order_ in classdict if name/value was not from a mapping 469 if not isinstance(item, basestring): 470 classdict['_order_'] = ' '.join(_order_) 471 enum_class = metacls.__new__(metacls, class_name, bases, classdict) 472 473 # TODO: replace the frame hack if a blessed way to know the calling 474 # module is ever developed 475 if module is None: 476 try: 477 module = _sys._getframe(2).f_globals['__name__'] 478 except (AttributeError, ValueError): 479 pass 480 if module is None: 481 _make_class_unpicklable(enum_class) 482 else: 483 enum_class.__module__ = module 484 485 return enum_class 486 487 @staticmethod 488 def _get_mixins_(bases): 489 """Returns the type for creating enum members, and the first inherited 490 enum class. 491 492 bases: the tuple of bases that was given to __new__ 493 494 """ 495 if not bases or Enum is None: 496 return object, Enum 497 498 499 # double check that we are not subclassing a class with existing 500 # enumeration members; while we're at it, see if any other data 501 # type has been mixed in so we can use the correct __new__ 502 member_type = first_enum = None 503 for base in bases: 504 if (base is not Enum and 505 issubclass(base, Enum) and 506 base._member_names_): 507 raise TypeError("Cannot extend enumerations") 508 # base is now the last base in bases 509 if not issubclass(base, Enum): 510 raise TypeError("new enumerations must be created as " 511 "`ClassName([mixin_type,] enum_type)`") 512 513 # get correct mix-in type (either mix-in type of Enum subclass, or 514 # first base if last base is Enum) 515 if not issubclass(bases[0], Enum): 516 member_type = bases[0] # first data type 517 first_enum = bases[-1] # enum type 518 else: 519 for base in bases[0].__mro__: 520 # most common: (IntEnum, int, Enum, object) 521 # possible: (<Enum 'AutoIntEnum'>, <Enum 'IntEnum'>, 522 # <class 'int'>, <Enum 'Enum'>, 523 # <class 'object'>) 524 if issubclass(base, Enum): 525 if first_enum is None: 526 first_enum = base 527 else: 528 if member_type is None: 529 member_type = base 530 531 return member_type, first_enum 532 533 if pyver < 3.0: 534 @staticmethod 535 def _find_new_(classdict, member_type, first_enum): 536 """Returns the __new__ to be used for creating the enum members. 537 538 classdict: the class dictionary given to __new__ 539 member_type: the data type whose __new__ will be used by default 540 first_enum: enumeration to check for an overriding __new__ 541 542 """ 543 # now find the correct __new__, checking to see of one was defined 544 # by the user; also check earlier enum classes in case a __new__ was 545 # saved as __member_new__ 546 __new__ = classdict.get('__new__', None) 547 if __new__: 548 return None, True, True # __new__, save_new, use_args 549 550 N__new__ = getattr(None, '__new__') 551 O__new__ = getattr(object, '__new__') 552 if Enum is None: 553 E__new__ = N__new__ 554 else: 555 E__new__ = Enum.__dict__['__new__'] 556 # check all possibles for __member_new__ before falling back to 557 # __new__ 558 for method in ('__member_new__', '__new__'): 559 for possible in (member_type, first_enum): 560 try: 561 target = possible.__dict__[method] 562 except (AttributeError, KeyError): 563 target = getattr(possible, method, None) 564 if target not in [ 565 None, 566 N__new__, 567 O__new__, 568 E__new__, 569 ]: 570 if method == '__member_new__': 571 classdict['__new__'] = target 572 return None, False, True 573 if isinstance(target, staticmethod): 574 target = target.__get__(member_type) 575 __new__ = target 576 break 577 if __new__ is not None: 578 break 579 else: 580 __new__ = object.__new__ 581 582 # if a non-object.__new__ is used then whatever value/tuple was 583 # assigned to the enum member name will be passed to __new__ and to the 584 # new enum member's __init__ 585 if __new__ is object.__new__: 586 use_args = False 587 else: 588 use_args = True 589 590 return __new__, False, use_args 591 else: 592 @staticmethod 593 def _find_new_(classdict, member_type, first_enum): 594 """Returns the __new__ to be used for creating the enum members. 595 596 classdict: the class dictionary given to __new__ 597 member_type: the data type whose __new__ will be used by default 598 first_enum: enumeration to check for an overriding __new__ 599 600 """ 601 # now find the correct __new__, checking to see of one was defined 602 # by the user; also check earlier enum classes in case a __new__ was 603 # saved as __member_new__ 604 __new__ = classdict.get('__new__', None) 605 606 # should __new__ be saved as __member_new__ later? 607 save_new = __new__ is not None 608 609 if __new__ is None: 610 # check all possibles for __member_new__ before falling back to 611 # __new__ 612 for method in ('__member_new__', '__new__'): 613 for possible in (member_type, first_enum): 614 target = getattr(possible, method, None) 615 if target not in ( 616 None, 617 None.__new__, 618 object.__new__, 619 Enum.__new__, 620 ): 621 __new__ = target 622 break 623 if __new__ is not None: 624 break 625 else: 626 __new__ = object.__new__ 627 628 # if a non-object.__new__ is used then whatever value/tuple was 629 # assigned to the enum member name will be passed to __new__ and to the 630 # new enum member's __init__ 631 if __new__ is object.__new__: 632 use_args = False 633 else: 634 use_args = True 635 636 return __new__, save_new, use_args 637 638 639######################################################## 640# In order to support Python 2 and 3 with a single 641# codebase we have to create the Enum methods separately 642# and then use the `type(name, bases, dict)` method to 643# create the class. 644######################################################## 645temp_enum_dict = {} 646temp_enum_dict['__doc__'] = "Generic enumeration.\n\n Derive from this class to define new enumerations.\n\n" 647 648def __new__(cls, value): 649 # all enum instances are actually created during class construction 650 # without calling this method; this method is called by the metaclass' 651 # __call__ (i.e. Color(3) ), and by pickle 652 if type(value) is cls: 653 # For lookups like Color(Color.red) 654 value = value.value 655 #return value 656 # by-value search for a matching enum member 657 # see if it's in the reverse mapping (for hashable values) 658 try: 659 if value in cls._value2member_map_: 660 return cls._value2member_map_[value] 661 except TypeError: 662 # not there, now do long search -- O(n) behavior 663 for member in cls._member_map_.values(): 664 if member.value == value: 665 return member 666 raise ValueError("%s is not a valid %s" % (value, cls.__name__)) 667temp_enum_dict['__new__'] = __new__ 668del __new__ 669 670def __repr__(self): 671 return "<%s.%s: %r>" % ( 672 self.__class__.__name__, self._name_, self._value_) 673temp_enum_dict['__repr__'] = __repr__ 674del __repr__ 675 676def __str__(self): 677 return "%s.%s" % (self.__class__.__name__, self._name_) 678temp_enum_dict['__str__'] = __str__ 679del __str__ 680 681if pyver >= 3.0: 682 def __dir__(self): 683 added_behavior = [ 684 m 685 for cls in self.__class__.mro() 686 for m in cls.__dict__ 687 if m[0] != '_' and m not in self._member_map_ 688 ] 689 return (['__class__', '__doc__', '__module__', ] + added_behavior) 690 temp_enum_dict['__dir__'] = __dir__ 691 del __dir__ 692 693def __format__(self, format_spec): 694 # mixed-in Enums should use the mixed-in type's __format__, otherwise 695 # we can get strange results with the Enum name showing up instead of 696 # the value 697 698 # pure Enum branch 699 if self._member_type_ is object: 700 cls = str 701 val = str(self) 702 # mix-in branch 703 else: 704 cls = self._member_type_ 705 val = self.value 706 return cls.__format__(val, format_spec) 707temp_enum_dict['__format__'] = __format__ 708del __format__ 709 710 711#################################### 712# Python's less than 2.6 use __cmp__ 713 714if pyver < 2.6: 715 716 def __cmp__(self, other): 717 if type(other) is self.__class__: 718 if self is other: 719 return 0 720 return -1 721 return NotImplemented 722 raise TypeError("unorderable types: %s() and %s()" % (self.__class__.__name__, other.__class__.__name__)) 723 temp_enum_dict['__cmp__'] = __cmp__ 724 del __cmp__ 725 726else: 727 728 def __le__(self, other): 729 raise TypeError("unorderable types: %s() <= %s()" % (self.__class__.__name__, other.__class__.__name__)) 730 temp_enum_dict['__le__'] = __le__ 731 del __le__ 732 733 def __lt__(self, other): 734 raise TypeError("unorderable types: %s() < %s()" % (self.__class__.__name__, other.__class__.__name__)) 735 temp_enum_dict['__lt__'] = __lt__ 736 del __lt__ 737 738 def __ge__(self, other): 739 raise TypeError("unorderable types: %s() >= %s()" % (self.__class__.__name__, other.__class__.__name__)) 740 temp_enum_dict['__ge__'] = __ge__ 741 del __ge__ 742 743 def __gt__(self, other): 744 raise TypeError("unorderable types: %s() > %s()" % (self.__class__.__name__, other.__class__.__name__)) 745 temp_enum_dict['__gt__'] = __gt__ 746 del __gt__ 747 748 749def __eq__(self, other): 750 if type(other) is self.__class__: 751 return self is other 752 return NotImplemented 753temp_enum_dict['__eq__'] = __eq__ 754del __eq__ 755 756def __ne__(self, other): 757 if type(other) is self.__class__: 758 return self is not other 759 return NotImplemented 760temp_enum_dict['__ne__'] = __ne__ 761del __ne__ 762 763def __hash__(self): 764 return hash(self._name_) 765temp_enum_dict['__hash__'] = __hash__ 766del __hash__ 767 768def __reduce_ex__(self, proto): 769 return self.__class__, (self._value_, ) 770temp_enum_dict['__reduce_ex__'] = __reduce_ex__ 771del __reduce_ex__ 772 773# _RouteClassAttributeToGetattr is used to provide access to the `name` 774# and `value` properties of enum members while keeping some measure of 775# protection from modification, while still allowing for an enumeration 776# to have members named `name` and `value`. This works because enumeration 777# members are not set directly on the enum class -- __getattr__ is 778# used to look them up. 779 780@_RouteClassAttributeToGetattr 781def name(self): 782 return self._name_ 783temp_enum_dict['name'] = name 784del name 785 786@_RouteClassAttributeToGetattr 787def value(self): 788 return self._value_ 789temp_enum_dict['value'] = value 790del value 791 792@classmethod 793def _convert(cls, name, module, filter, source=None): 794 """ 795 Create a new Enum subclass that replaces a collection of global constants 796 """ 797 # convert all constants from source (or module) that pass filter() to 798 # a new Enum called name, and export the enum and its members back to 799 # module; 800 # also, replace the __reduce_ex__ method so unpickling works in 801 # previous Python versions 802 module_globals = vars(_sys.modules[module]) 803 if source: 804 source = vars(source) 805 else: 806 source = module_globals 807 members = dict((name, value) for name, value in source.items() if filter(name)) 808 cls = cls(name, members, module=module) 809 cls.__reduce_ex__ = _reduce_ex_by_name 810 module_globals.update(cls.__members__) 811 module_globals[name] = cls 812 return cls 813temp_enum_dict['_convert'] = _convert 814del _convert 815 816Enum = EnumMeta('Enum', (object, ), temp_enum_dict) 817del temp_enum_dict 818 819# Enum has now been created 820########################### 821 822class IntEnum(int, Enum): 823 """Enum where members are also (and must be) ints""" 824 825def _reduce_ex_by_name(self, proto): 826 return self.name 827 828def unique(enumeration): 829 """Class decorator that ensures only unique members exist in an enumeration.""" 830 duplicates = [] 831 for name, member in enumeration.__members__.items(): 832 if name != member.name: 833 duplicates.append((name, member.name)) 834 if duplicates: 835 duplicate_names = ', '.join( 836 ["%s -> %s" % (alias, name) for (alias, name) in duplicates] 837 ) 838 raise ValueError('duplicate names found in %r: %s' % 839 (enumeration, duplicate_names) 840 ) 841 return enumeration 842