Package Bio :: Module PropertyManager
[hide private]
[frames] | no frames]

Source Code for Module Bio.PropertyManager

 1  # Stores properties associated with the class of an object. 
 2   
 3   
 4  # Would it be nice to have support for more than one resolver per 
 5  # class?  In the meanwhile, they could collude using a dispatch 
 6  # object. 
 7   
 8  # Do you need access to the actual resolver? 
 9   
10  # Resolvers get the sequence because they may do a per-object lookup. 
11   
12  # Could cache search results for better performance. 
13   
14   
15  # Dictionary which creates dictionary elements, so lookups never fail. 
16  # The new elements are always dictionaries. 
17 -class CreateDict(dict):
18 - def __getitem__(self, key):
19 return self.setdefault(key,{})
20
21 -class PropertyManager:
22 - def __init__(self):
23 self.class_property = CreateDict() 24 self.class_property_resolver = CreateDict() 25 self.class_resolver = {}
26
27 - def resolve(self, obj, property):
28 try: 29 klass = obj.__class__ 30 except AttributeError: 31 raise KeyError("built-in instance") 32 33 return self.resolve_class(klass, property)
34
35 - def resolve_class(self, klass, property):
36 # Hopefully, we'll find the hit right away 37 try: 38 return self.class_property[klass][property] 39 except KeyError: 40 pass 41 42 # Is there a property resolver? 43 try: 44 return self.class_property_resolver[klass][property]( 45 self, klass, property) 46 except KeyError: 47 pass 48 49 # What about the class resolver? 50 try: 51 return self.class_resolver[klass](self, klass, property) 52 except KeyError: 53 pass 54 55 # That failed, so we walk up the class tree, depth-first and 56 # left-to-right (same as Python). For each class, check if 57 # the property exists, then check if the property resolver 58 # exists, and finally, check for the class resolver. 59 60 bases = list(klass.__bases__) 61 while bases: 62 base = bases.pop() 63 try: 64 return self.class_property[base][property] 65 except KeyError: 66 pass 67 try: 68 return self.class_property_resolver[base][property]( 69 self, klass, property) 70 except KeyError: 71 pass 72 try: 73 return self.class_resolver[base](self, klass, property) 74 except KeyError: 75 pass 76 77 # this is why the search is depth-first/right-left 78 bases[:0] = list(base.__bases__) 79 raise KeyError("cannot find property %s for class %s" \ 80 % (property, klass))
81 82 83 default_manager = PropertyManager() 84