[Zope3-checkins] SVN: Zope3/trunk/src/zope/interface/ Fix the same bug as we had in lookup(). We did not choose the right set of

Stephan Richter srichter at cosmos.phy.tufts.edu
Fri Sep 24 17:16:07 EDT 2004


Log message for revision 27682:
  Fix the same bug as we had in lookup(). We did not choose the right set of 
  interfaces until now for multi-adapters. Thanks goes to Gustavo Niemeyer 
  again, who provided the patch.
  
  


Changed:
  U   Zope3/trunk/src/zope/interface/adapter.py
  U   Zope3/trunk/src/zope/interface/tests/test_adapter.py


-=-
Modified: Zope3/trunk/src/zope/interface/adapter.py
===================================================================
--- Zope3/trunk/src/zope/interface/adapter.py	2004-09-24 18:32:02 UTC (rev 27681)
+++ Zope3/trunk/src/zope/interface/adapter.py	2004-09-24 21:16:07 UTC (rev 27682)
@@ -569,15 +569,27 @@
                 if not bywith or name in first:
                     continue
 
+                # See comments on lookup() above
+                best  = None
                 for rwith, value in bywith:
+                    # the `rank` describes how well the found adapter matches.
+                    rank = []
                     for rspec, spec in zip(rwith, with):
                         if not spec.isOrExtends(rspec):
                             break # This one is no good
+                        # Determine the rank of this particular specification.
+                        rank.append(list(spec.__sro__).index(rspec))
                     else:
-                        # Got this far, we have a match
-                        yield name, value
-                        break
+                        # If the new rank is better than the best previously
+                        # recorded one, make the new adapter the best one found.
+                        rank = tuple(rank)
+                        if best is None or rank < best[0]:
+                            best = rank, value
 
+                # If any match was found, return the best one.
+                if best:
+                    yield name, best[1]
+
             first = byname
 
     def subscribe(self, required, provided, value):

Modified: Zope3/trunk/src/zope/interface/tests/test_adapter.py
===================================================================
--- Zope3/trunk/src/zope/interface/tests/test_adapter.py	2004-09-24 18:32:02 UTC (rev 27681)
+++ Zope3/trunk/src/zope/interface/tests/test_adapter.py	2004-09-24 21:16:07 UTC (rev 27682)
@@ -80,6 +80,34 @@
     'A1'
     """
 
+def test_multi_adapter_lookupAll_get_best_matches():
+    """
+    >>> registry = AdapterRegistry()
+
+    >>> class IB2(IB0):
+    ...     pass
+    >>> class IB3(IB2, IB1):
+    ...     pass
+    >>> class IB4(IB1, IB2):
+    ...     pass
+
+    >>> registry.register([None, IB1], IR0, '', 'A1')
+    >>> registry.register([None, IB0], IR0, '', 'A0')
+    >>> registry.register([None, IB2], IR0, '', 'A2')
+
+    >>> registry.lookupAll((IF1, IB1), IR0).next()[1]
+    'A1'
+    >>> registry.lookupAll((IF1, IB2), IR0).next()[1]
+    'A2'
+    >>> registry.lookupAll((IF1, IB0), IR0).next()[1]
+    'A0'
+    >>> registry.lookupAll((IF1, IB3), IR0).next()[1]
+    'A2'
+    >>> registry.lookupAll((IF1, IB4), IR0).next()[1]
+    'A1'
+    """
+
+
 def test_multi_adapter_w_default():
     """
     >>> registry = AdapterRegistry()



More information about the Zope3-Checkins mailing list