[Zope-Checkins] SVN: Products.Five/trunk/ svn merge -r65405:65496 from branches/regebro-localutility-fix.

Lennart Regebro regebro at gmail.com
Sun Feb 26 15:45:09 EST 2006


Log message for revision 65499:
  svn merge -r65405:65496 from branches/regebro-localutility-fix.
  
  * A local utility registered with an derived interface will now be available
    by the inherited interface as well, in the same way as Zope3.
  
  

Changed:
  U   Products.Five/trunk/CHANGES.txt
  U   Products.Five/trunk/site/tests/test_utility.py
  U   Products.Five/trunk/site/utility.py

-=-
Modified: Products.Five/trunk/CHANGES.txt
===================================================================
--- Products.Five/trunk/CHANGES.txt	2006-02-26 20:35:07 UTC (rev 65498)
+++ Products.Five/trunk/CHANGES.txt	2006-02-26 20:45:08 UTC (rev 65499)
@@ -23,6 +23,12 @@
   NOTE: Anyone who copied the Five site.zcml to their
   $INSTANCE_HOME/etc/ directory is going to need to update it.
 
+Bugfixes
+--------
+
+* A local utility registered with an derived interface will now be available
+  by the inherited interface as well, in the same way as Zope3.
+
 Five 1.3.2 (2006-02-25)
 =======================
 
@@ -33,7 +39,7 @@
   When no Zope 3-style view is found, first the object's original
   ``__bobo_traverse__`` is tried.  If that does not exist, Traversable
   resorts to attribute look-up.
-
+  
 * Unit tests that did i18n via Localizer would fail because the
   request attribute that keeps Localizers list of preferred languages
   did not exist.

Modified: Products.Five/trunk/site/tests/test_utility.py
===================================================================
--- Products.Five/trunk/site/tests/test_utility.py	2006-02-26 20:35:07 UTC (rev 65498)
+++ Products.Five/trunk/site/tests/test_utility.py	2006-02-26 20:45:08 UTC (rev 65499)
@@ -81,7 +81,7 @@
 
     def test_getUtilitiesNoUtilitiesFolder(self):
         sm = zapi.getSiteManager()
-        #XXX test whether sm really is a local site...
+        
         self.failUnless(sm.queryUtility(IDummyUtility) is None)
         self.assertEquals(list(sm.getUtilitiesFor(IDummyUtility)), [])
         self.assertEquals(list(sm.getAllUtilitiesRegisteredFor(IDummyUtility)), [])
@@ -122,6 +122,49 @@
         self.assertEquals(zapi.getUtility(ISuperDummyUtility, 'dummy'),
                           superdummy)
 
+    def test_derivedInterfaceRegistration(self):
+        # Utilities providing a derived interface should be listed
+        # when you ask for an interface. So ask for IDummmyInterace, and
+        # anything registered for IDummyInterface of ISuperDummyInterface
+        # should come back.
+
+        sm = zapi.getSiteManager()
+        self.failUnless(IRegisterUtilitySimply.providedBy(sm))
+        dummy = DummyUtility()
+        superdummy = DummyUtility()
+        directlyProvides(superdummy, ISuperDummyUtility)
+        uts = list(sm.getUtilitiesFor(IDummyUtility))
+        self.failUnlessEqual(uts, [])
+
+        sm.registerUtility(ISuperDummyUtility, superdummy)
+        
+        # We should be able to access this utility both with 
+        # IDummyUtility and ISuperDummyUtility interfaces:
+        uts = list(sm.getUtilitiesFor(IDummyUtility))
+        self.failUnless(uts[0][1].aq_base is superdummy)
+        uts = list(sm.getUtilitiesFor(ISuperDummyUtility))
+        self.failUnless(uts[0][1].aq_base is superdummy)
+        
+        # Also try that the standard zapi call works:
+        ut = zapi.getUtility(IDummyUtility, context=self.folder.site)
+        self.failUnless(ut.aq_base is superdummy)
+        ut = zapi.getUtility(ISuperDummyUtility, context=self.folder.site)
+        self.failUnless(ut.aq_base is superdummy)
+    
+        # If we register a second utility we should find both utilities
+        # when looking for the base interface
+        sm.registerUtility(IDummyUtility, dummy)
+
+        uts = list(sm.getAllUtilitiesRegisteredFor(IDummyUtility))
+        self.failUnless(dummy in uts)
+        self.failUnless(superdummy in uts)
+
+        # But we should find only one when looking for the derived interface
+        uts = list(sm.getAllUtilitiesRegisteredFor(ISuperDummyUtility))
+        self.failUnless(dummy not in uts)
+        self.failUnless(superdummy in uts)
+
+
     def test_nestedSitesDontConflictButStillAcquire(self):
         # let's register a dummy utility in the dummy site
         dummy = DummyUtility()

Modified: Products.Five/trunk/site/utility.py
===================================================================
--- Products.Five/trunk/site/utility.py	2006-02-26 20:35:07 UTC (rev 65498)
+++ Products.Five/trunk/site/utility.py	2006-02-26 20:45:08 UTC (rev 65499)
@@ -51,29 +51,22 @@
     def queryUtility(self, interface, name='', default=None):
         """See IFiveUtilityRegistry interface
         """
-        if name == '':
-            # Singletons. Only one per interface allowed, so, let's call it
-            # by the interface.
-            id = interface.getName()
-        else:
-            id = interface.getName() + '-' + name
-
         if getattr(aq_base(self.context), 'utilities', None) is not None:
-            utility = self.context.utilities._getOb(id, None)
-            if utility is not None:
-                return utility
+            for id, utility in self.context.utilities.objectItems():
+                if (interface.providedBy(utility) and
+                    (name == '' or id.endswith(name))):
+                        return utility
         return self.next.queryUtility(interface, name, default)
 
     def getUtilitiesFor(self, interface):
         names = []
-        prefix = interface.getName() + '-'
         if getattr(aq_base(self.context), 'utilities', None) is not None:
-            for name, utility in self.context.utilities.objectItems():
-                if name == interface.getName():
-                    names.append('')
-                    yield '', utility
-                elif name.startswith(prefix):
-                    name = name[len(prefix):]
+            for id, utility in self.context.utilities.objectItems():
+                if interface.providedBy(utility):
+                    if id.find('-') != -1:
+                        prefix, name = id.split('-', 1)
+                    else:
+                        name = ''
                     names.append(name)
                     yield (name, utility)
         for name, utility in self.next.getUtilitiesFor(interface):



More information about the Zope-Checkins mailing list