Change Eclipse configuration
[jabaws.git] / website / archive / binaries / mac / src / disembl / biopython-1.50 / Bio / PropertyManager.py
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()