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): _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins