[Zope3-checkins] CVS: Zope3/src/zope/interface - surrogate.py:1.1.2.11

Jim Fulton cvs-admin at zope.org
Thu Nov 13 12:33:32 EST 2003


Update of /cvs-repository/Zope3/src/zope/interface
In directory cvs.zope.org:/tmp/cvs-serv12014/src/zope/interface

Modified Files:
      Tag: adaptergeddon-branch
	surrogate.py 
Log Message:
Fixed some bugs in multi-adapters.


=== Zope3/src/zope/interface/surrogate.py 1.1.2.10 => 1.1.2.11 ===
--- Zope3/src/zope/interface/surrogate.py:1.1.2.10	Wed Nov 12 15:08:15 2003
+++ Zope3/src/zope/interface/surrogate.py	Thu Nov 13 12:33:00 2003
@@ -436,46 +436,47 @@
         obs = objects[1:]
 
         declaration = providedBy(ob)
-        s = self.get(declaration)
+        surrogate = self.get(declaration)
 
-        adapters = s.get((interface, name, order))
-        if adapters is None:
-            adapters = self._default.get((interface, name, order))
-
-        if adapters:
-            matched = None
-            matched_factories = None
-            for interfaces, factories in adapters.iteritems():
-                for iface, ob in zip(interfaces, obs):
-                    if not iface.isImplementedBy(ob):
-                        break # This one is no good
-                else:
-                    # we didn't break, so we have a match
-                    if matched is None:
-                        matched = interfaces
-                        matched_factories = factories
+        while 1:
+            adapters = surrogate.get((interface, name, order))
+            if adapters:
+                matched = None
+                matched_factories = None
+                for interfaces, factories in adapters.iteritems():
+                    for iface, ob in zip(interfaces, obs):
+                        if not iface.isImplementedBy(ob):
+                            break # This one is no good
                     else:
-                        for iface, m in zip(interfaces, matched):
-                            if iface.extends(m):
-                                # new is better than old
-                                matched = interfaces
-                                matched_factories = factories
-                                break
-                            elif m.extends(iface):
-                                # old is better than new
-                                break                
+                        # we didn't break, so we have a match
+                        if matched is None:
+                            matched = interfaces
+                            matched_factories = factories
+                        else:
+                            # see if the new match is better than the old one:
+                            for iface, m in zip(interfaces, matched):
+                                if iface.extends(m):
+                                    # new is better than old
+                                    matched = interfaces
+                                    matched_factories = factories
+                                    break
+                                elif m.extends(iface):
+                                    # old is better than new
+                                    break
+                                
 
-            if matched_factories is None:
-                return default
-            
-            if raw:
-                return matched_factories
+                if matched_factories is not None:
+                    if raw:
+                        return matched_factories
 
-            assert len(matched_factories) == 1
+                    assert len(matched_factories) == 1
 
-            return matched_factories[0](*objects)
+                    return matched_factories[0](*objects)
 
-        return default
+            # Fall back to default if we haven't already
+            if surrogate is self._default:
+                return default
+            surrogate = self._default
 
     def getRegisteredMatching(self,
                               required_interfaces=None,
@@ -653,10 +654,11 @@
     # Add adapters and interfaces directly implied by same:
     for (with, name, target), factories in adapters.iteritems():
         if with:
-            _add_multi_adapter(with, name, target, target, multi, factories)
+            _add_multi_adapter(with, name, target, target, multi,
+                               registered, factories)
         elif name:
-            _add_named_adapter(target, target, name, implied, registered,
-                               factories)
+            _add_named_adapter(target, target, name, implied,
+                               registered, factories)
         else:
             _add_adapter(target, target, implied, registered, factories)
 
@@ -685,14 +687,23 @@
             _add_named_adapter(b, provided, name,
                                implied, registered, factories)
 
-def _add_multi_adapter(interfaces, name, target, provided, implied, factories):
+def _add_multi_adapter(interfaces, name, target, provided, implied,
+                       registered, factories):
     order = len(interfaces)+1
-    adapters = implied.get((target, name, order))
+    key = target, name, order
+    adapters = implied.get(key)
     if adapters is None:
         adapters = {}
-        implied[(target, name, order)] = adapters
+        implied[key] = adapters
 
-    adapters.setdefault(interfaces, factories)
+    key = key, interfaces # The full key has all 4
+    if key not in registered or registered[key].extends(provided):
+        # This is either a new entry or it is an entry for a more
+        # general interface that is closer provided than what we had
+        # before
+        registered[key] = provided
+        adapters[interfaces] = factories
 
     for b in target.__bases__:
-        _add_multi_adapter(interfaces, name, b, provided, implied, factories)
+        _add_multi_adapter(interfaces, name, b, provided, implied,
+                           registered, factories)




More information about the Zope3-Checkins mailing list