Package flumotion :: Package common :: Module enum
[hide private]

Source Code for Module flumotion.common.enum

  1  # -*- Mode: Python; test-case-name: flumotion.test.test_enum -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3  # 
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com). 
  6  # All rights reserved. 
  7   
  8  # This file may be distributed and/or modified under the terms of 
  9  # the GNU General Public License version 2 as published by 
 10  # the Free Software Foundation. 
 11  # This file is distributed without any warranty; without even the implied 
 12  # warranty of merchantability or fitness for a particular purpose. 
 13  # See "LICENSE.GPL" in the source distribution for more information. 
 14   
 15  # Licensees having purchased or holding a valid Flumotion Advanced 
 16  # Streaming Server license may use this file in accordance with the 
 17  # Flumotion Advanced Streaming Server Commercial License Agreement. 
 18  # See "LICENSE.Flumotion" in the source distribution for more information. 
 19   
 20  # Headers in this file shall remain intact. 
 21   
 22  """simple enum and implementation 
 23  """ 
 24   
 25  from twisted.python.reflect import qual 
 26  from twisted.spread import jelly 
 27   
 28  __version__ = "$Rev$" 
 29  _enumClassRegistry = {} 
 30   
 31   
32 -class EnumMetaClass(type):
33 # pychecker likes this attribute to be there since we use it in this class 34 __enums__ = {} 35
36 - def __len__(self):
37 return len(self.__enums__)
38
39 - def __getitem__(self, value):
40 try: 41 return self.__enums__[value] 42 except KeyError: 43 raise StopIteration
44
45 - def __setitem__(self, value, enum):
46 self.__enums__[value] = enum 47 setattr(self, enum.name, enum)
48 49
50 -class Enum(object, jelly.Jellyable):
51 52 __metaclass__ = EnumMetaClass 53
54 - def __init__(self, value, name, nick=None):
55 self.value = value 56 self.name = name 57 58 if nick == None: 59 nick = name 60 61 self.nick = nick 62 self._enumClassName = self.__class__.__name__
63
64 - def __repr__(self):
65 return '<enum %s of type %s>' % (self.name, 66 self.__class__.__name__)
67
68 - def get(klass, value):
69 return klass.__enums__[value]
70 get = classmethod(get) 71
72 - def set(klass, value, item):
73 klass[value] = item
74 set = classmethod(set) 75
76 - def jellyFor(self, jellier):
77 sxp = jellier.prepare(self) 78 sxp.extend([ 79 qual(Enum), 80 self._enumClassName, 81 self.value, self.name, self.nick]) 82 return jellier.preserve(self, sxp)
83 84
85 -class EnumClass(object):
86
87 - def __new__(klass, type_name, names=(), nicks=(), **extras):
88 if nicks: 89 if len(names) != len(nicks): 90 raise TypeError("nicks must have the same length as names") 91 else: 92 nicks = names 93 94 for extra in extras.values(): 95 if not isinstance(extra, (tuple, list)): 96 raise TypeError( 97 'extra must be a sequence, not %s' % type(extra)) 98 99 if len(extra) != len(names): 100 raise TypeError("extra items must have a length of %d" % 101 len(names)) 102 103 # we reset __enums__ to {} otherwise it retains the other registered 104 # ones 105 etype = EnumMetaClass(type_name, (Enum, ), {'__enums__': {}}) 106 for value, name in enumerate(names): 107 enum = etype(value, name, nicks[value]) 108 for extra_key, extra_values in extras.items(): 109 assert not hasattr(enum, extra_key) 110 setattr(enum, extra_key, extra_values[value]) 111 etype[value] = enum 112 113 _enumClassRegistry[type_name] = etype 114 return etype
115 116 117 # Enum unjellyer should not be a new style class, 118 # otherwise Twsited 2.0.1 will not recognise it. 119 120
121 -class EnumUnjellyer(jelly.Unjellyable):
122
123 - def unjellyFor(self, unjellier, jellyList):
124 enumClassName, value, name, nick = jellyList[1:] 125 enumClass = _enumClassRegistry.get(enumClassName, None) 126 if enumClass: 127 # Retrieve the enum singleton 128 enum = enumClass.get(value) 129 assert enum.name == name, "Inconsistent Enum Name" 130 else: 131 # Create a generic Enum container 132 enum = Enum(value, name, nick) 133 enum._enumClassName = enumClassName 134 return enum
135 136 137 jelly.setUnjellyableForClass(qual(Enum), EnumUnjellyer) 138