Package suds :: Module sudsobject
[hide private]
[frames] | no frames]

Source Code for Module suds.sudsobject

  1  # This program is free software; you can redistribute it and/or modify 
  2  # it under the terms of the (LGPL) GNU Lesser General Public License as 
  3  # published by the Free Software Foundation; either version 3 of the  
  4  # License, or (at your option) any later version. 
  5  # 
  6  # This program is distributed in the hope that it will be useful, 
  7  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  8  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  9  # GNU Library Lesser General Public License for more details at 
 10  # ( http://www.gnu.org/licenses/lgpl.html ). 
 11  # 
 12  # You should have received a copy of the GNU Lesser General Public License 
 13  # along with this program; if not, write to the Free Software 
 14  # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
 15  # written by: Jeff Ortel ( jortel@redhat.com ) 
 16   
 17  """ 
 18  The I{sudsobject} module provides a collection of suds objects 
 19  that are primarily used for the highly dynamic interactions with 
 20  wsdl/xsd defined types. 
 21  """ 
 22   
 23  from logging import getLogger 
 24  from suds import * 
 25  from new import classobj 
 26   
 27  log = getLogger(__name__) 
28 29 30 -def items(sobject):
31 """ 32 Extract the I{items} from a suds object much like the 33 items() method works on I{dict}. 34 @param sobject: A suds object 35 @type sobject: L{Object} 36 @return: A list of items contained in I{sobject}. 37 @rtype: [(key, value),...] 38 """ 39 for item in sobject: 40 yield item
41
42 43 -def asdict(sobject):
44 """ 45 Convert a sudsobject into a dictionary. 46 @param sobject: A suds object 47 @type sobject: L{Object} 48 @return: A python dictionary containing the 49 items contained in I{sobject}. 50 @rtype: dict 51 """ 52 return dict(items(sobject))
53
54 -def merge(a, b):
55 """ 56 Merge all attributes and metadata from I{a} to I{b}. 57 @param a: A I{source} object 58 @type a: L{Object} 59 @param b: A I{destination} object 60 @type b: L{Object} 61 """ 62 for item in a: 63 setattr(b, item[0], item[1]) 64 b.__metadata__ = b.__metadata__ 65 return b
66
67 -def footprint(sobject):
68 """ 69 Get the I{virtual footprint} of the object. 70 This is really a count of the attributes in the branch with a significant value. 71 @param sobject: A suds object. 72 @type sobject: L{Object} 73 @return: The branch footprint. 74 @rtype: int 75 """ 76 n = 0 77 for a in sobject.__keylist__: 78 v = getattr(sobject, a) 79 if v is None: continue 80 if isinstance(v, Object): 81 n += footprint(v) 82 continue 83 if hasattr(v, '__len__'): 84 if len(v): n += 1 85 continue 86 n +=1 87 return n
88
89 90 -class Factory:
91 92 cache = {} 93 94 @classmethod
95 - def subclass(cls, name, bases, dict={}):
96 if not isinstance(bases, tuple): 97 bases = (bases,) 98 name = name.encode('utf-8') 99 key = '.'.join((name, str(bases))) 100 subclass = cls.cache.get(key) 101 if subclass is None: 102 subclass = classobj(name, bases, dict) 103 cls.cache[key] = subclass 104 return subclass
105 106 @classmethod
107 - def object(cls, classname=None, dict={}):
108 if classname is not None: 109 subclass = cls.subclass(classname, Object) 110 inst = subclass() 111 else: 112 inst = Object() 113 for a in dict.items(): 114 setattr(inst, a[0], a[1]) 115 return inst
116 117 @classmethod
118 - def metadata(cls):
119 return Metadata()
120 121 @classmethod
122 - def property(cls, name, value=None):
123 subclass = cls.subclass(name, Property) 124 return subclass(value)
125
126 127 -class Object:
128
129 - def __init__(self):
130 self.__keylist__ = [] 131 self.__printer__ = Printer() 132 self.__metadata__ = Metadata()
133
134 - def __setattr__(self, name, value):
135 builtin = name.startswith('__') and name.endswith('__') 136 if not builtin and \ 137 name not in self.__keylist__: 138 self.__keylist__.append(name) 139 self.__dict__[name] = value
140
141 - def __delattr__(self, name):
142 try: 143 del self.__dict__[name] 144 builtin = name.startswith('__') and name.endswith('__') 145 if not builtin: 146 self.__keylist__.remove(name) 147 except: 148 cls = self.__class__.__name__ 149 raise AttributeError, "%s has no attribute '%s'" % (cls, name)
150
151 - def __getitem__(self, name):
152 if isinstance(name, int): 153 name = self.__keylist__[int(name)] 154 return getattr(self, name)
155
156 - def __setitem__(self, name, value):
157 setattr(self, name, value)
158
159 - def __iter__(self):
160 return Iter(self)
161
162 - def __len__(self):
163 return len(self.__keylist__)
164
165 - def __contains__(self, name):
166 return name in self.__keylist__
167
168 - def __repr__(self):
169 return str(self)
170
171 - def __str__(self):
172 return unicode(self).encode('utf-8')
173
174 - def __unicode__(self):
175 return self.__printer__.tostr(self)
176
177 178 -class Iter:
179
180 - def __init__(self, sobject):
181 self.sobject = sobject 182 self.keylist = self.__keylist(sobject) 183 self.index = 0
184
185 - def next(self):
186 keylist = self.keylist 187 nkeys = len(self.keylist) 188 while self.index < nkeys: 189 k = keylist[self.index] 190 self.index += 1 191 if hasattr(self.sobject, k): 192 v = getattr(self.sobject, k) 193 return (k, v) 194 raise StopIteration()
195
196 - def __keylist(self, sobject):
197 keylist = sobject.__keylist__ 198 try: 199 keyset = set(keylist) 200 ordering = sobject.__metadata__.ordering 201 ordered = set(ordering) 202 if not ordered.issuperset(keyset): 203 log.debug( 204 '%s must be superset of %s, ordering ignored', 205 keylist, 206 ordering) 207 raise KeyError() 208 return ordering 209 except: 210 return keylist
211
212 - def __iter__(self):
213 return self
214
215 216 -class Metadata(Object):
217 - def __init__(self):
218 self.__keylist__ = [] 219 self.__printer__ = Printer()
220
221 222 -class Facade(Object):
223 - def __init__(self, name):
224 Object.__init__(self) 225 md = self.__metadata__ 226 md.facade = name
227
228 229 -class Property(Object):
230
231 - def __init__(self, value):
232 Object.__init__(self) 233 self.value = value
234
235 - def items(self):
236 for item in self: 237 if item[0] != 'value': 238 yield item
239
240 - def get(self):
241 return self.value
242
243 - def set(self, value):
244 self.value = value 245 return self
246
247 248 -class Printer:
249 """ 250 Pretty printing of a Object object. 251 """ 252 253 @classmethod
254 - def indent(cls, n): return '%*s'%(n*3,' ')
255
256 - def tostr(self, object, indent=-2):
257 """ get s string representation of object """ 258 history = [] 259 return self.process(object, history, indent)
260
261 - def process(self, object, h, n=0, nl=False):
262 """ print object using the specified indent (n) and newline (nl). """ 263 if object is None: 264 return 'None' 265 if isinstance(object, Object): 266 if len(object) == 0: 267 return '<empty>' 268 else: 269 return self.print_object(object, h, n+2, nl) 270 if isinstance(object, dict): 271 if len(object) == 0: 272 return '<empty>' 273 else: 274 return self.print_dictionary(object, h, n+2, nl) 275 if isinstance(object, (list,tuple)): 276 if len(object) == 0: 277 return '<empty>' 278 else: 279 return self.print_collection(object, h, n+2) 280 if isinstance(object, basestring): 281 return '"%s"' % tostr(object) 282 return '%s' % tostr(object)
283
284 - def print_object(self, d, h, n, nl=False):
285 """ print complex using the specified indent (n) and newline (nl). """ 286 s = [] 287 cls = d.__class__ 288 md = d.__metadata__ 289 if d in h: 290 s.append('(') 291 s.append(cls.__name__) 292 s.append(')') 293 s.append('...') 294 return ''.join(s) 295 h.append(d) 296 if nl: 297 s.append('\n') 298 s.append(self.indent(n)) 299 if cls != Object: 300 s.append('(') 301 if isinstance(d, Facade): 302 s.append(md.facade) 303 else: 304 s.append(cls.__name__) 305 s.append(')') 306 s.append('{') 307 for item in d: 308 if self.exclude(d, item): 309 continue 310 item = self.unwrap(d, item) 311 s.append('\n') 312 s.append(self.indent(n+1)) 313 if isinstance(item[1], (list,tuple)): 314 s.append(item[0]) 315 s.append('[]') 316 else: 317 s.append(item[0]) 318 s.append(' = ') 319 s.append(self.process(item[1], h, n, True)) 320 s.append('\n') 321 s.append(self.indent(n)) 322 s.append('}') 323 h.pop() 324 return ''.join(s)
325
326 - def print_dictionary(self, d, h, n, nl=False):
327 """ print complex using the specified indent (n) and newline (nl). """ 328 if d in h: return '{}...' 329 h.append(d) 330 s = [] 331 if nl: 332 s.append('\n') 333 s.append(self.indent(n)) 334 s.append('{') 335 for item in d.items(): 336 s.append('\n') 337 s.append(self.indent(n+1)) 338 if isinstance(item[1], (list,tuple)): 339 s.append(tostr(item[0])) 340 s.append('[]') 341 else: 342 s.append(tostr(item[0])) 343 s.append(' = ') 344 s.append(self.process(item[1], h, n, True)) 345 s.append('\n') 346 s.append(self.indent(n)) 347 s.append('}') 348 h.pop() 349 return ''.join(s)
350
351 - def print_collection(self, c, h, n):
352 """ print collection using the specified indent (n) and newline (nl). """ 353 if c in h: return '[]...' 354 h.append(c) 355 s = [] 356 for item in c: 357 s.append('\n') 358 s.append(self.indent(n)) 359 s.append(self.process(item, h, n-2)) 360 s.append(',') 361 h.pop() 362 return ''.join(s)
363
364 - def unwrap(self, d, item):
365 """ translate (unwrap) using an optional wrapper function """ 366 nopt = ( lambda x: x ) 367 try: 368 md = d.__metadata__ 369 pmd = getattr(md, '__print__', None) 370 if pmd is None: 371 return item 372 wrappers = getattr(pmd, 'wrappers', {}) 373 fn = wrappers.get(item[0], nopt) 374 return (item[0], fn(item[1])) 375 except: 376 pass 377 return item
378
379 - def exclude(self, d, item):
380 """ check metadata for excluded items """ 381 try: 382 md = d.__metadata__ 383 pmd = getattr(md, '__print__', None) 384 if pmd is None: 385 return False 386 excludes = getattr(pmd, 'excludes', []) 387 return ( item[0] in excludes ) 388 except: 389 pass 390 return False
391