Package horizons :: Package ext :: Module enum
[hide private]
[frames] | no frames]

Source Code for Module horizons.ext.enum

  1  # -*- coding: utf-8 -*- 
  2   
  3  # enum.py 
  4  # Part of enum, a package providing enumerated types for Python. 
  5  # 
  6  # Copyright © 2007–2009 Ben Finney <ben+python@benfinney.id.au> 
  7  # This is free software; you may copy, modify and/or distribute this work 
  8  # under the terms of the GNU General Public License, version 2 or later 
  9  # or, at your option, the terms of the Python license. 
 10   
 11  """ Robust enumerated type support in Python. 
 12   
 13  This package provides a module for robust enumerations in Python. 
 14   
 15  An enumeration object is created with a sequence of string arguments 
 16  to the Enum() constructor:: 
 17   
 18      >>> from enum import Enum 
 19      >>> Colors = Enum('red', 'blue', 'green') 
 20      >>> Weekdays = Enum('mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun') 
 21   
 22  The return value is an immutable sequence object with a value for each 
 23  of the string arguments. Each value is also available as an attribute 
 24  named from the corresponding string argument:: 
 25   
 26      >>> pizza_night = Weekdays[4] 
 27      >>> shirt_color = Colors.green 
 28   
 29  The values are constants that can be compared only with values from 
 30  the same enumeration; comparison with other values will invoke 
 31  Python's fallback comparisons:: 
 32   
 33      >>> pizza_night == Weekdays.fri 
 34      True 
 35      >>> shirt_color > Colors.red 
 36      True 
 37      >>> shirt_color == "green" 
 38      False 
 39   
 40  Each value from an enumeration exports its sequence index 
 41  as an integer, and can be coerced to a simple string matching the 
 42  original arguments used to create the enumeration:: 
 43   
 44      >>> str(pizza_night) 
 45      'fri' 
 46      >>> shirt_color.index 
 47      2 
 48  """ 
 49   
 50  __author_name__ = "Ben Finney" 
 51  __author_email__ = "ben+python@benfinney.id.au" 
 52  __author__ = "%(__author_name__)s <%(__author_email__)s>" % vars() 
 53   
 54  _copyright_year_begin = "2007" 
 55  __date__ = "2009-08-26" 
 56  _copyright_year_latest = __date__.split('-')[0] 
 57  _copyright_year_range = _copyright_year_begin 
 58  if _copyright_year_latest > _copyright_year_begin: 
 59          _copyright_year_range += "–%(_copyright_year_latest)s" % vars() 
 60  __copyright__ = ( 
 61          "Copyright © %(_copyright_year_range)s" 
 62          " %(__author_name__)s") % vars() 
 63  __license__ = "Choice of GPL or Python license" 
 64   
 65  __url__ = "http://pypi.python.org/pypi/enum/" 
 66  __version__ = "0.4.4" 
67 68 69 -class EnumException(Exception):
70 """ Base class for all exceptions in this module. """ 71
72 - def __init__(self, *args, **kwargs):
73 if self.__class__ is EnumException: 74 class_name = self.__class__.__name__ 75 raise NotImplementedError( 76 "%(class_name)s is an abstract base class" % vars()) 77 super().__init__(*args, **kwargs)
78
79 80 -class EnumEmptyError(AssertionError, EnumException):
81 """ Raised when attempting to create an empty enumeration. """ 82
83 - def __str__(self):
84 return "Enumerations cannot be empty"
85
86 87 -class EnumBadKeyError(TypeError, EnumException):
88 """ Raised when creating an Enum with non-string keys. """ 89
90 - def __init__(self, key):
91 self.key = key
92
93 - def __str__(self):
94 return "Enumeration keys must be strings: %(key)r" % vars(self)
95
96 97 -class EnumImmutableError(TypeError, EnumException):
98 """ Raised when attempting to modify an Enum. """ 99
100 - def __init__(self, *args):
101 self.args = args
102
103 - def __str__(self):
104 return "Enumeration does not allow modification"
105
106 107 -def _comparator(func):
108 """ Decorator for EnumValue rich comparison methods. """ 109 def comparator_wrapper(self, other): 110 try: 111 assert self.enumtype == other.enumtype 112 result = func(self.index, other.index) 113 except (AssertionError, AttributeError): 114 result = NotImplemented 115 116 return result
117 comparator_wrapper.__name__ = func.__name__ 118 comparator_wrapper.__doc__ = getattr(float, func.__name__).__doc__ 119 return comparator_wrapper 120
121 122 -class EnumValue:
123 """ A specific value of an enumerated type. """ 124
125 - def __init__(self, enumtype, index, key):
126 """ Set up a new instance. """ 127 self._enumtype = enumtype 128 self._index = index 129 self._key = key
130 131 @property
132 - def enumtype(self):
133 return self._enumtype
134 135 @property
136 - def key(self):
137 return self._key
138
139 - def __str__(self):
140 return str(self.key)
141 142 @property
143 - def index(self):
144 return self._index
145
146 - def __repr__(self):
147 return "EnumValue(%(_enumtype)r, %(_index)r, %(_key)r)" % vars(self)
148
149 - def __hash__(self):
150 return hash(self._index)
151 152 @_comparator
153 - def __eq__(self, other):
154 return (self == other)
155 156 @_comparator
157 - def __ne__(self, other):
158 return (self != other)
159 160 @_comparator
161 - def __lt__(self, other):
162 return (self < other)
163 164 @_comparator
165 - def __le__(self, other):
166 return (self <= other)
167 168 @_comparator
169 - def __gt__(self, other):
170 return (self > other)
171 172 @_comparator
173 - def __ge__(self, other):
174 return (self >= other)
175
176 177 -class Enum:
178 """ Enumerated type. """ 179
180 - def __init__(self, *keys, **kwargs):
181 """ Create an enumeration instance. """ 182 183 value_type = kwargs.get('value_type', EnumValue) 184 185 if not keys: 186 raise EnumEmptyError() 187 188 keys = tuple(keys) 189 values = [None] * len(keys) 190 191 for i, key in enumerate(keys): 192 value = value_type(self, i, key) 193 values[i] = value 194 try: 195 super().__setattr__(key, value) 196 except TypeError: 197 raise EnumBadKeyError(key) 198 199 self.__dict__['_keys'] = keys 200 self.__dict__['_values'] = values
201 202 @classmethod
203 - def get_extended(cls, base_enum, *keys, **kwargs):
204 keys = base_enum._keys + keys 205 return cls(*keys, **kwargs)
206
207 - def __setattr__(self, name, value):
209
210 - def __delattr__(self, name):
212
213 - def __len__(self):
214 return len(self._values)
215
216 - def __getitem__(self, index):
217 return self._values[index]
218
219 - def __setitem__(self, index, value):
221
222 - def __delitem__(self, index):
224
225 - def __iter__(self):
226 return iter(self._values)
227
228 - def __contains__(self, value):
229 is_member = False 230 if isinstance(value, str): 231 is_member = (value in self._keys) 232 else: 233 is_member = (value in self._values) 234 return is_member
235
236 - def get_item_for_string(self, key):
237 """Get an enum value for a string 238 @throws KeyError on key not found""" 239 try: 240 index = self._keys.index(key) 241 except ValueError: 242 raise KeyError # keyerror is more natural here, since the value is a key 243 return self[index]
244