Package solvcon :: Module gendata
[hide private]
[frames] | no frames]

Source Code for Module solvcon.gendata

  1  # -*- coding: UTF-8 -*- 
  2  # 
  3  # Copyright (C) 2008-2010 Yung-Yu Chen <yyc@solvcon.net>. 
  4  # 
  5  # This program is free software; you can redistribute it and/or modify 
  6  # it under the terms of the GNU General Public License as published by 
  7  # the Free Software Foundation; either version 2 of the License, or 
  8  # (at your option) any later version. 
  9  # 
 10  # This program is distributed in the hope that it will be useful, 
 11  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 13  # GNU General Public License for more details. 
 14  # 
 15  # You should have received a copy of the GNU General Public License along 
 16  # with this program; if not, write to the Free Software Foundation, Inc., 
 17  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 18   
 19  """ 
 20  Generic data structures. 
 21  """ 
22 23 -class AttributeDict(dict):
24 """ 25 Dictionary form which key can be assessed as attribute. 26 """
27 - def __getattr__(self, name):
28 """ 29 Consult self dictionary for attribute. It's a shorthand. 30 """ 31 return self[name]
32 - def __setattr__(self, name, value):
33 """ 34 Save to self dictionary first, then self object table. 35 36 @note: This method is overriden as a stupid-preventer. It makes 37 attribute setting consistent with attribute getting. 38 """ 39 if name in self: 40 self[name] = value 41 else: 42 super(AttributeDict, self).__setattr__(name, value)
43
44 -class DefaultDict(dict):
45 """ 46 Dictionary with default values. 47 48 @cvar defdict: dictionary for default values. 49 @type defdict: dict 50 """ 51 defdict = {}
52 - def __init__(self, *args, **kw):
53 """ 54 Assign default values to self after initiated. 55 """ 56 super(DefaultDict, self).__init__(*args, **kw) 57 for key in self.defdict: 58 self[key] = self.defdict[key]
59
60 -class SingleAssignDict(dict):
61 """ 62 Dictionary in which key/value can only be assigned once. 63 """
64 - def __setitem__(self, key, item):
65 """ 66 Check for duplicated assignment. 67 """ 68 if key in self: 69 raise IndexError, "Cannot reset value for key=%s to override %s."%( 70 str(key), str(self[key])) 71 super(SingleAssignDict, self).__setitem__(key, item)
72
73 -class TypeNameRegistry(SingleAssignDict, AttributeDict):
74 """ 75 Registry class for the name of types. 76 """
77 - def register(self, tobj):
78 self[tobj.__name__] = tobj 79 return tobj
80
81 -class Timer(dict):
82 """ 83 Timer dictionary with increase method. 84 """
85 - def __init__(self, *args, **kw):
86 self.vtype = kw.pop('vtype', float) 87 super(Timer, self).__init__(*args, **kw)
88 - def increase(self, key, delta):
89 self[key] = self.get(key, self.vtype(0)) + self.vtype(delta)
90
91 # Define the base metaclass for classes want binders. 92 -def bind(self):
93 """ 94 Set up pointers. All attributes which are pointers have to be 95 initialized here. 96 """ 97 pass
98 -def unbind(self):
99 """ 100 Release pointer. 101 """ 102 for key in self._pointers_: 103 setattr(self, key, None)
104 @property
105 -def is_bound(self):
106 """ 107 Determine if all the pointers are fully bound. 108 """ 109 for key in self._pointers_: 110 if getattr(self, key, None)==None: 111 return False 112 return True
113 @property
114 -def is_unbound(self):
115 """ 116 Determine if all the pointers are fully unbound. 117 """ 118 for key in self._pointers_: 119 if getattr(self, key, None)!=None: 120 return False 121 return True
122 -class TypeWithBinder(type):
123 """ 124 Meta class to make classes with ctypes pointers or containers with ctypes 125 pointers. The type will feather classes with bind/unbind methods along 126 with is_bound/is_unbound properties. The names of pointer variables have 127 to be listed in _pointers_ class list variable. 128 129 The bind/unbind methods are designed to be applied to pointers used by the 130 instance. is_bound/is_unbound properties can test for if pointers are 131 fully bound or fully unbound to the instance, respectively. You have to 132 override the bind method and initiate pointers in it rather than in other 133 method. You can leave it alone if you don't need it. Be sure to enter 134 correct entries into the _pointers_ class variable. 135 136 @cvar _pointers_: a list containing names of variables for ctypes pointers, 137 ctypes structures, or containers that hold ctypes pointers. The list 138 would be used in binding/unbinding process. Subclassing does not 139 override the content of this list. The names defined in the 140 superclasses will be prepended in front of anything in the list defined 141 in the subclass. 142 @ctype _pointers_: list 143 """
144 - def __new__(cls, name, bases, namespace):
145 # incremental modification of _pointers_. 146 pointers = [] 147 for base in bases: 148 pointers.extend(getattr(base, '_pointers_', [])) 149 pointers.extend(namespace.get('_pointers_', [])) 150 namespace['_pointers_'] = pointers 151 # supply the default binding methods and properties for classes without 152 # their definitions. 153 for key in ('bind', 'unbind', 'is_bound', 'is_unbound'): 154 if namespace.get(key, None) != None: 155 continue 156 nokeyinbases = True 157 for base in bases: 158 if getattr(base, key, None) != None: 159 nokeyinbases = False 160 break 161 if nokeyinbases: 162 namespace[key] = globals()[key] 163 # return. 164 return super(TypeWithBinder, cls).__new__(cls, name, bases, namespace)
165