__init__.py (18792B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\enum\__init__.py 2 import sys as _sys 3 __all__ = ['Enum', 'IntEnum', 'unique'] 4 version = (1, 1, 10) 5 pyver = float('%s.%s' % _sys.version_info[:2]) 6 try: 7 any 8 except NameError: 9 10 def any(iterable): 11 for element in iterable: 12 if element: 13 return True 14 15 return False 16 17 18 try: 19 from collections import OrderedDict 20 except ImportError: 21 OrderedDict = None 22 23 try: 24 basestring 25 except NameError: 26 basestring = str 27 28 try: 29 unicode 30 except NameError: 31 unicode = str 32 33 class _RouteClassAttributeToGetattr(object): 34 35 def __init__(self, fget = None): 36 self.fget = fget 37 38 def __get__(self, instance, ownerclass = None): 39 if instance is None: 40 raise AttributeError() 41 return self.fget(instance) 42 43 def __set__(self, instance, value): 44 raise AttributeError("can't set attribute") 45 46 def __delete__(self, instance): 47 raise AttributeError("can't delete attribute") 48 49 50 def _is_descriptor(obj): 51 return hasattr(obj, '__get__') or hasattr(obj, '__set__') or hasattr(obj, '__delete__') 52 53 54 def _is_dunder(name): 55 return name[:2] == name[-2:] == '__' and name[2:3] != '_' and name[-3:-2] != '_' and len(name) > 4 56 57 58 def _is_sunder(name): 59 return name[0] == name[-1] == '_' and name[1:2] != '_' and name[-2:-1] != '_' and len(name) > 2 60 61 62 def _make_class_unpicklable(cls): 63 64 def _break_on_call_reduce(self, protocol = None): 65 raise TypeError('%r cannot be pickled' % self) 66 67 cls.__reduce_ex__ = _break_on_call_reduce 68 cls.__module__ = '<unknown>' 69 70 71 class _EnumDict(dict): 72 73 def __init__(self): 74 super(_EnumDict, self).__init__() 75 self._member_names = [] 76 77 def __setitem__(self, key, value): 78 if pyver >= 3.0 and key in ('_order_', '__order__'): 79 return 80 if key == '__order__': 81 key = '_order_' 82 if _is_sunder(key): 83 if key != '_order_': 84 raise ValueError('_names_ are reserved for future Enum use') 85 elif _is_dunder(key): 86 pass 87 elif key in self._member_names: 88 raise TypeError('Attempted to reuse key: %r' % key) 89 elif not _is_descriptor(value): 90 if key in self: 91 raise TypeError('Key already defined as: %r' % self[key]) 92 self._member_names.append(key) 93 super(_EnumDict, self).__setitem__(key, value) 94 95 96 Enum = None 97 98 class EnumMeta(type): 99 100 @classmethod 101 def __prepare__(metacls, cls, bases): 102 return _EnumDict() 103 104 def __new__(metacls, cls, bases, classdict): 105 if type(classdict) is dict: 106 original_dict = classdict 107 classdict = _EnumDict() 108 for k, v in original_dict.items(): 109 classdict[k] = v 110 111 member_type, first_enum = metacls._get_mixins_(bases) 112 __new__, save_new, use_args = metacls._find_new_(classdict, member_type, first_enum) 113 members = dict(((k, classdict[k]) for k in classdict._member_names)) 114 for name in classdict._member_names: 115 del classdict[name] 116 117 _order_ = classdict.get('_order_') 118 if _order_ is None: 119 if pyver < 3.0: 120 try: 121 _order_ = [ name for name, value in sorted(members.items(), key=lambda item: item[1]) ] 122 except TypeError: 123 _order_ = [ name for name in sorted(members.keys()) ] 124 125 else: 126 _order_ = classdict._member_names 127 else: 128 del classdict['_order_'] 129 if pyver < 3.0: 130 if isinstance(_order_, basestring): 131 _order_ = _order_.replace(',', ' ').split() 132 aliases = [ name for name in members if name not in _order_ ] 133 _order_ += aliases 134 invalid_names = set(members) & set(['mro']) 135 if invalid_names: 136 raise ValueError('Invalid enum member name(s): %s' % (', '.join(invalid_names),)) 137 base_attributes = set([ a for b in bases for a in b.__dict__ ]) 138 enum_class = super(EnumMeta, metacls).__new__(metacls, cls, bases, classdict) 139 enum_class._member_names_ = [] 140 if OrderedDict is not None: 141 enum_class._member_map_ = OrderedDict() 142 else: 143 enum_class._member_map_ = {} 144 enum_class._member_type_ = member_type 145 enum_class._value2member_map_ = {} 146 if __new__ is None: 147 __new__ = enum_class.__new__ 148 for member_name in _order_: 149 value = members[member_name] 150 if not isinstance(value, tuple): 151 args = (value,) 152 else: 153 args = value 154 if member_type is tuple: 155 args = (args,) 156 if not use_args or not args: 157 enum_member = __new__(enum_class) 158 if not hasattr(enum_member, '_value_'): 159 enum_member._value_ = value 160 else: 161 enum_member = __new__(enum_class, *args) 162 if not hasattr(enum_member, '_value_'): 163 enum_member._value_ = member_type(*args) 164 value = enum_member._value_ 165 enum_member._name_ = member_name 166 enum_member.__objclass__ = enum_class 167 enum_member.__init__(*args) 168 for name, canonical_member in enum_class._member_map_.items(): 169 if canonical_member.value == enum_member._value_: 170 enum_member = canonical_member 171 break 172 else: 173 enum_class._member_names_.append(member_name) 174 175 if member_name not in base_attributes: 176 setattr(enum_class, member_name, enum_member) 177 enum_class._member_map_[member_name] = enum_member 178 try: 179 enum_class._value2member_map_[value] = enum_member 180 except TypeError: 181 pass 182 183 unpicklable = False 184 if '__reduce_ex__' not in classdict: 185 if member_type is not object: 186 methods = ('__getnewargs_ex__', '__getnewargs__', '__reduce_ex__', '__reduce__') 187 if not any((m in member_type.__dict__ for m in methods)): 188 _make_class_unpicklable(enum_class) 189 unpicklable = True 190 for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'): 191 class_method = getattr(enum_class, name) 192 obj_method = getattr(member_type, name, None) 193 enum_method = getattr(first_enum, name, None) 194 if name not in classdict and class_method is not enum_method: 195 if name == '__reduce_ex__' and unpicklable: 196 continue 197 setattr(enum_class, name, enum_method) 198 199 if pyver < 2.6: 200 if issubclass(enum_class, int): 201 setattr(enum_class, '__cmp__', getattr(int, '__cmp__')) 202 elif pyver < 3.0: 203 if issubclass(enum_class, int): 204 for method in ('__le__', '__lt__', '__gt__', '__ge__', '__eq__', '__ne__', '__hash__'): 205 setattr(enum_class, method, getattr(int, method)) 206 207 if Enum is not None: 208 if save_new: 209 setattr(enum_class, '__member_new__', enum_class.__dict__['__new__']) 210 setattr(enum_class, '__new__', Enum.__dict__['__new__']) 211 return enum_class 212 213 def __bool__(cls): 214 return True 215 216 def __call__(cls, value, names = None, module = None, type = None, start = 1): 217 if names is None: 218 return cls.__new__(cls, value) 219 return cls._create_(value, names, module=module, type=type, start=start) 220 221 def __contains__(cls, member): 222 return isinstance(member, cls) and member.name in cls._member_map_ 223 224 def __delattr__(cls, attr): 225 if attr in cls._member_map_: 226 raise AttributeError('%s: cannot delete Enum member.' % cls.__name__) 227 super(EnumMeta, cls).__delattr__(attr) 228 229 def __dir__(self): 230 return ['__class__', 231 '__doc__', 232 '__members__', 233 '__module__'] + self._member_names_ 234 235 @property 236 def __members__(cls): 237 return cls._member_map_.copy() 238 239 def __getattr__(cls, name): 240 if _is_dunder(name): 241 raise AttributeError(name) 242 try: 243 return cls._member_map_[name] 244 except KeyError: 245 raise AttributeError(name) 246 247 def __getitem__(cls, name): 248 return cls._member_map_[name] 249 250 def __iter__(cls): 251 return (cls._member_map_[name] for name in cls._member_names_) 252 253 def __reversed__(cls): 254 return (cls._member_map_[name] for name in reversed(cls._member_names_)) 255 256 def __len__(cls): 257 return len(cls._member_names_) 258 259 __nonzero__ = __bool__ 260 261 def __repr__(cls): 262 return '<enum %r>' % cls.__name__ 263 264 def __setattr__(cls, name, value): 265 member_map = cls.__dict__.get('_member_map_', {}) 266 if name in member_map: 267 raise AttributeError('Cannot reassign members.') 268 super(EnumMeta, cls).__setattr__(name, value) 269 270 def _create_(cls, class_name, names = None, module = None, type = None, start = 1): 271 if pyver < 3.0: 272 if isinstance(class_name, unicode): 273 try: 274 class_name = class_name.encode('ascii') 275 except UnicodeEncodeError: 276 raise TypeError('%r is not representable in ASCII' % class_name) 277 278 metacls = cls.__class__ 279 if type is None: 280 bases = (cls,) 281 else: 282 bases = (type, cls) 283 classdict = metacls.__prepare__(class_name, bases) 284 _order_ = [] 285 if isinstance(names, basestring): 286 names = names.replace(',', ' ').split() 287 if isinstance(names, (tuple, list)) and isinstance(names[0], basestring): 288 names = [ (e, i + start) for i, e in enumerate(names) ] 289 item = None 290 for item in names: 291 if isinstance(item, basestring): 292 member_name, member_value = item, names[item] 293 else: 294 member_name, member_value = item 295 classdict[member_name] = member_value 296 _order_.append(member_name) 297 298 if not isinstance(item, basestring): 299 classdict['_order_'] = _order_ 300 enum_class = metacls.__new__(metacls, class_name, bases, classdict) 301 if module is None: 302 try: 303 module = _sys._getframe(2).f_globals['__name__'] 304 except (AttributeError, ValueError): 305 pass 306 307 if module is None: 308 _make_class_unpicklable(enum_class) 309 else: 310 enum_class.__module__ = module 311 return enum_class 312 313 @staticmethod 314 def _get_mixins_(bases): 315 if not bases or Enum is None: 316 return (object, Enum) 317 member_type = first_enum = None 318 for base in bases: 319 if base is not Enum and issubclass(base, Enum) and base._member_names_: 320 raise TypeError('Cannot extend enumerations') 321 322 if not issubclass(base, Enum): 323 raise TypeError('new enumerations must be created as `ClassName([mixin_type,] enum_type)`') 324 if not issubclass(bases[0], Enum): 325 member_type = bases[0] 326 first_enum = bases[-1] 327 else: 328 for base in bases[0].__mro__: 329 if issubclass(base, Enum): 330 if first_enum is None: 331 first_enum = base 332 elif member_type is None: 333 member_type = base 334 335 return (member_type, first_enum) 336 337 if pyver < 3.0: 338 339 @staticmethod 340 def _find_new_(classdict, member_type, first_enum): 341 __new__ = classdict.get('__new__', None) 342 if __new__: 343 return (None, True, True) 344 N__new__ = getattr(None, '__new__') 345 O__new__ = getattr(object, '__new__') 346 if Enum is None: 347 E__new__ = N__new__ 348 else: 349 E__new__ = Enum.__dict__['__new__'] 350 for method in ('__member_new__', '__new__'): 351 for possible in (member_type, first_enum): 352 try: 353 target = possible.__dict__[method] 354 except (AttributeError, KeyError): 355 target = getattr(possible, method, None) 356 357 if target not in [None, 358 N__new__, 359 O__new__, 360 E__new__]: 361 if method == '__member_new__': 362 classdict['__new__'] = target 363 return (None, False, True) 364 if isinstance(target, staticmethod): 365 target = target.__get__(member_type) 366 __new__ = target 367 break 368 369 if __new__ is not None: 370 break 371 else: 372 __new__ = object.__new__ 373 374 if __new__ is object.__new__: 375 use_args = False 376 else: 377 use_args = True 378 return (__new__, False, use_args) 379 380 else: 381 382 @staticmethod 383 def _find_new_(classdict, member_type, first_enum): 384 __new__ = classdict.get('__new__', None) 385 save_new = __new__ is not None 386 if __new__ is None: 387 for method in ('__member_new__', '__new__'): 388 for possible in (member_type, first_enum): 389 target = getattr(possible, method, None) 390 if target not in (None, 391 None.__new__, 392 object.__new__, 393 Enum.__new__): 394 __new__ = target 395 break 396 397 if __new__ is not None: 398 break 399 else: 400 __new__ = object.__new__ 401 402 if __new__ is object.__new__: 403 use_args = False 404 else: 405 use_args = True 406 return (__new__, save_new, use_args) 407 408 409 temp_enum_dict = {} 410 temp_enum_dict['__doc__'] = 'Generic enumeration.\n\n Derive from this class to define new enumerations.\n\n' 411 412 def __new__(cls, value): 413 if type(value) is cls: 414 value = value.value 415 try: 416 if value in cls._value2member_map_: 417 return cls._value2member_map_[value] 418 except TypeError: 419 for member in cls._member_map_.values(): 420 if member.value == value: 421 return member 422 423 raise ValueError('%s is not a valid %s' % (value, cls.__name__)) 424 425 426 temp_enum_dict['__new__'] = __new__ 427 del __new__ 428 429 def __repr__(self): 430 return '<%s.%s: %r>' % (self.__class__.__name__, self._name_, self._value_) 431 432 433 temp_enum_dict['__repr__'] = __repr__ 434 del __repr__ 435 436 def __str__(self): 437 return '%s.%s' % (self.__class__.__name__, self._name_) 438 439 440 temp_enum_dict['__str__'] = __str__ 441 del __str__ 442 if pyver >= 3.0: 443 444 def __dir__(self): 445 added_behavior = [ m for cls in self.__class__.mro() for m in cls.__dict__ if m[0] != '_' and m not in self._member_map_ ] 446 return ['__class__', '__doc__', '__module__'] + added_behavior 447 448 449 temp_enum_dict['__dir__'] = __dir__ 450 del __dir__ 451 452 def __format__(self, format_spec): 453 if self._member_type_ is object: 454 cls = str 455 val = str(self) 456 else: 457 cls = self._member_type_ 458 val = self.value 459 return cls.__format__(val, format_spec) 460 461 462 temp_enum_dict['__format__'] = __format__ 463 del __format__ 464 if pyver < 2.6: 465 466 def __cmp__(self, other): 467 if type(other) is self.__class__: 468 if self is other: 469 return 0 470 return -1 471 return NotImplemented 472 raise TypeError('unorderable types: %s() and %s()' % (self.__class__.__name__, other.__class__.__name__)) 473 474 475 temp_enum_dict['__cmp__'] = __cmp__ 476 del __cmp__ 477 else: 478 479 def __le__(self, other): 480 raise TypeError('unorderable types: %s() <= %s()' % (self.__class__.__name__, other.__class__.__name__)) 481 482 483 temp_enum_dict['__le__'] = __le__ 484 del __le__ 485 486 def __lt__(self, other): 487 raise TypeError('unorderable types: %s() < %s()' % (self.__class__.__name__, other.__class__.__name__)) 488 489 490 temp_enum_dict['__lt__'] = __lt__ 491 del __lt__ 492 493 def __ge__(self, other): 494 raise TypeError('unorderable types: %s() >= %s()' % (self.__class__.__name__, other.__class__.__name__)) 495 496 497 temp_enum_dict['__ge__'] = __ge__ 498 del __ge__ 499 500 def __gt__(self, other): 501 raise TypeError('unorderable types: %s() > %s()' % (self.__class__.__name__, other.__class__.__name__)) 502 503 504 temp_enum_dict['__gt__'] = __gt__ 505 del __gt__ 506 507 def __eq__(self, other): 508 if type(other) is self.__class__: 509 return self is other 510 return NotImplemented 511 512 513 temp_enum_dict['__eq__'] = __eq__ 514 del __eq__ 515 516 def __ne__(self, other): 517 if type(other) is self.__class__: 518 return self is not other 519 return NotImplemented 520 521 522 temp_enum_dict['__ne__'] = __ne__ 523 del __ne__ 524 525 def __hash__(self): 526 return hash(self._name_) 527 528 529 temp_enum_dict['__hash__'] = __hash__ 530 del __hash__ 531 532 def __reduce_ex__(self, proto): 533 return (self.__class__, (self._value_,)) 534 535 536 temp_enum_dict['__reduce_ex__'] = __reduce_ex__ 537 del __reduce_ex__ 538 539 @_RouteClassAttributeToGetattr 540 def name(self): 541 return self._name_ 542 543 544 temp_enum_dict['name'] = name 545 del name 546 547 @_RouteClassAttributeToGetattr 548 def value(self): 549 return self._value_ 550 551 552 temp_enum_dict['value'] = value 553 del value 554 555 @classmethod 556 def _convert(cls, name, module, filter, source = None): 557 module_globals = vars(_sys.modules[module]) 558 if source: 559 source = vars(source) 560 else: 561 source = module_globals 562 members = dict(((name, value) for name, value in source.items() if filter(name))) 563 cls = cls(name, members, module=module) 564 cls.__reduce_ex__ = _reduce_ex_by_name 565 module_globals.update(cls.__members__) 566 module_globals[name] = cls 567 return cls 568 569 570 temp_enum_dict['_convert'] = _convert 571 del _convert 572 Enum = EnumMeta('Enum', (object,), temp_enum_dict) 573 del temp_enum_dict 574 575 class IntEnum(int, Enum): 576 pass 577 578 579 def _reduce_ex_by_name(self, proto): 580 return self.name 581 582 583 def unique(enumeration): 584 duplicates = [] 585 for name, member in enumeration.__members__.items(): 586 if name != member.name: 587 duplicates.append((name, member.name)) 588 589 if duplicates: 590 duplicate_names = ', '.join([ '%s -> %s' % (alias, name) for alias, name in duplicates ]) 591 raise ValueError('duplicate names found in %r: %s' % (enumeration, duplicate_names)) 592 return enumeration 593 594 595 from .ext import AutoNumber