Skip to content

Instantly share code, notes, and snippets.

@agronholm
Created July 7, 2014 18:57
Show Gist options
  • Save agronholm/879c18d186079c9de75c to your computer and use it in GitHub Desktop.
Save agronholm/879c18d186079c9de75c to your computer and use it in GitHub Desktop.
Enums with integer values
class IntegerEnumWrapper(TypeDecorator):
impl = Integer
def __init__(self, cls):
TypeDecorator.__init__(self)
self.wrapped = cls
def process_bind_param(self, value, dialect):
if value is None:
return None
if isinstance(value, self.wrapped):
return value.index
raise TypeError('Expected %s, got %s instead' % (self.wrapped, type(value)))
def process_result_value(self, value, dialect):
return self.wrapped.values[value] if value is not None else None
class EnumMeta(type):
def __new__(cls, name, bases, dct):
values = []
for key, value in dct.items():
if not key.startswith('_') and isinstance(value, (tuple, basestring)):
value = (0, value) if not isinstance(value, tuple) else value
values.append((key, value))
del dct[key]
newclass = type.__new__(cls, name, bases, dct)
for i in xrange(len(values)):
key, value = values[i]
instance = newclass(key, *value)
values[i] = instance
setattr(newclass, key, instance)
newclass.values = tuple(sorted(values))
return newclass
class EnumObject(object):
__metaclass__ = EnumMeta
def __init__(self, key, index, label):
self.key = key
self.index = index
self.label = label
def __eq__(self, other):
return isinstance(other, self.__class__) and other.key == self.key
def __ne__(self, other):
return not self.__eq__(other)
def __lt__(self, other):
if isinstance(other, self.__class__):
return self.index < other.index
return NotImplemented
def __getstate__(self):
return {'key': self.key}
def __setstate__(self, state):
key = state['key']
for value in self.values:
if value.key == key:
self.__dict__ = value.__dict__.copy()
return
raise TypeError('Value with key "%s" not found' % key)
def __unicode__(self):
return self.label
def __hash__(self):
return hash(self.key)
class Currency(EnumObject):
EUR = 0, 'EUR'
USD = 1, 'USD'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment