[Checkins] SVN: Sandbox/faassen/iface/src/iface/mapping. added the back-tracking multi-key look-up

Thomas Lotze tl at gocept.com
Wed Jan 6 19:11:03 EST 2010


Log message for revision 107757:
  added the back-tracking multi-key look-up

Changed:
  U   Sandbox/faassen/iface/src/iface/mapping.py
  U   Sandbox/faassen/iface/src/iface/mapping.txt

-=-
Modified: Sandbox/faassen/iface/src/iface/mapping.py
===================================================================
--- Sandbox/faassen/iface/src/iface/mapping.py	2010-01-06 23:39:24 UTC (rev 107756)
+++ Sandbox/faassen/iface/src/iface/mapping.py	2010-01-07 00:11:03 UTC (rev 107757)
@@ -49,7 +49,7 @@
         self._by_arity = {}
         
     def __setitem__(self, key, value):
-        arity = len(key)
+        arity = MapKey(len(key))
         key = (arity,) + tuple(key)
         map = self._by_arity
         for k in key[:-1]:
@@ -60,7 +60,7 @@
         map[key[-1]] = value
 
     def __delitem__(self, key):
-        arity = len(key)
+        arity = MapKey(len(key))
         key = (arity,) + tuple(key)
         map = self._by_arity
         for k in key[:-1]:
@@ -68,10 +68,16 @@
         del map[key[-1]]
 
     def __getitem__(self, key):
-        arity = len(key)
-        key = (arity,) + tuple(key)
+        arity = MapKey(len(key))
         map = self._by_arity
-        for k in key[:-1]:
-            map = map[k]
-        return map[key[-1]]
+        return self._getitem_recursive(map, arity, *key)
 
+    def _getitem_recursive(self, map, k, *key):
+        if not key:
+            return map[k]
+        for parent in k._parent_mapkeys:
+            try:
+                return self._getitem_recursive(map[parent], *key)
+            except KeyError, e:
+                pass
+        raise e

Modified: Sandbox/faassen/iface/src/iface/mapping.txt
===================================================================
--- Sandbox/faassen/iface/src/iface/mapping.txt	2010-01-06 23:39:24 UTC (rev 107756)
+++ Sandbox/faassen/iface/src/iface/mapping.txt	2010-01-07 00:11:03 UTC (rev 107757)
@@ -208,7 +208,27 @@
   Traceback (most recent call last):
     ...
   KeyError: <MapKey: 'two'>
+  >>> multimap[(beta, one)]
+  Traceback (most recent call last):
+    ...
+  KeyError: <MapKey: 'one'>
 
+After we provide a value for the least specific combination now, all of the
+latter look-ups will succeed by falling back to that value::
+
+  >>> multimap[(alpha, one)] = u'Value for alpha, one'
+
+  >>> multimap[(alpha, one)]
+  u'Value for alpha, one'
+  >>> multimap[(alpha, two)]
+  u'Value for alpha, one'
+  >>> multimap[(beta, one)]
+  u'Value for alpha, one'
+
+Note that in the case of looking up ``beta, one``, the look-up algorithm
+resorts to considering registered keys starting with the less specific
+``alpha`` in order to satisfy the requirement of the second component.
+
 next: multi lookup. What is the behavior of zope.interface? Do earlier
 entries in the lookup list always weigh more heavily than the second
 one? We need backtracking in case we don't find anything for the next



More information about the checkins mailing list