+++ /dev/null
-# Stores properties associated with the class of an object.
-
-
-# Would it be nice to have support for more than one resolver per
-# class? In the meanwhile, they could collude using a dispatch
-# object.
-
-# Do you need access to the actual resolver?
-
-# Resolvers get the sequence because they may do a per-object lookup.
-
-# Could cache search results for better performance.
-
-
-# Dictionary which creates dictionary elements, so lookups never fail.
-# The new elements are always dictionaries.
-class CreateDict(dict):
- def __getitem__(self, key):
- return self.setdefault(key,{})
-
-class PropertyManager:
- def __init__(self):
- self.class_property = CreateDict()
- self.class_property_resolver = CreateDict()
- self.class_resolver = {}
-
- def resolve(self, obj, property):
- try:
- klass = obj.__class__
- except AttributeError:
- raise KeyError("built-in instance")
-
- return self.resolve_class(klass, property)
-
- def resolve_class(self, klass, property):
- # Hopefully, we'll find the hit right away
- try:
- return self.class_property[klass][property]
- except KeyError:
- pass
-
- # Is there a property resolver?
- try:
- return self.class_property_resolver[klass][property](
- self, klass, property)
- except KeyError:
- pass
-
- # What about the class resolver?
- try:
- return self.class_resolver[klass](self, klass, property)
- except KeyError:
- pass
-
- # That failed, so we walk up the class tree, depth-first and
- # left-to-right (same as Python). For each class, check if
- # the property exists, then check if the property resolver
- # exists, and finally, check for the class resolver.
-
- bases = list(klass.__bases__)
- while bases:
- base = bases.pop()
- try:
- return self.class_property[base][property]
- except KeyError:
- pass
- try:
- return self.class_property_resolver[base][property](
- self, klass, property)
- except KeyError:
- pass
- try:
- return self.class_resolver[base](self, klass, property)
- except KeyError:
- pass
-
- # this is why the search is depth-first/right-left
- bases[:0] = list(base.__bases__)
- raise KeyError("cannot find property %s for class %s" \
- % (property, klass))
-
-
-default_manager = PropertyManager()