[Zope3-checkins] SVN: Zope3/trunk/src/zope/ Added a new method, getAllUtilitiesRegisteredFor that

Jim Fulton jim at zope.com
Sun May 23 12:57:52 EDT 2004


Log message for revision 24908:
Added a new method, getAllUtilitiesRegisteredFor that
allows one to find all utilities registered for an 
interface (or an interface extended by the interface), 
regardless of whether they have been overridden.

This is useful when you want to find all utilities
of a type to update them when an event has occured.




-=-
Modified: Zope3/trunk/src/zope/app/adapter/adapter.py
===================================================================
--- Zope3/trunk/src/zope/app/adapter/adapter.py	2004-05-23 16:31:13 UTC (rev 24907)
+++ Zope3/trunk/src/zope/app/adapter/adapter.py	2004-05-23 16:57:51 UTC (rev 24908)
@@ -23,6 +23,7 @@
 from zope.app.registration.registration import NotifyingRegistrationStack
 from zope.interface.adapter import adapterImplied, Default
 from zope.interface.adapter import Surrogate, AdapterRegistry
+from zope.proxy import removeAllProxies
 import sys
 import zope.app.component.localservice
 import zope.app.container.contained
@@ -143,13 +144,8 @@
 
         return stack
 
-    def adaptersChanged(self, *args):
 
-        adapters = {}
-        if self.next is not None:
-            for required, radapters in self.next.adapters.iteritems():
-                adapters[required] = radapters.copy()
-        
+    def _updateAdaptersFromLocalData(self, adapters):
         for required, stacks in self.stacks.iteritems():
             if required is None:
                 required = Default
@@ -161,10 +157,17 @@
             for key, stack in stacks.iteritems():
                 registration = stack.active()
                 if registration is not None:
-                    from zope.proxy import removeAllProxies
                     radapters[key] = removeAllProxies(registration.factory)
 
+    def adaptersChanged(self, *args):
 
+        adapters = {}
+        if self.next is not None:
+            for required, radapters in self.next.adapters.iteritems():
+                adapters[required] = radapters.copy()
+        
+        self._updateAdaptersFromLocalData(adapters)
+
         if adapters != self.adapters:
             self.adapters = adapters
 

Modified: Zope3/trunk/src/zope/app/utility/utility.py
===================================================================
--- Zope3/trunk/src/zope/app/utility/utility.py	2004-05-23 16:31:13 UTC (rev 24907)
+++ Zope3/trunk/src/zope/app/utility/utility.py	2004-05-23 16:57:51 UTC (rev 24908)
@@ -23,6 +23,7 @@
 from zope.app.utility.interfaces import ILocalUtilityService
 from zope.app.utility.interfaces import IUtilityRegistration
 from zope.component.utility import UtilityService
+from zope.proxy import removeAllProxies
 import zope.app.site.interfaces
 import zope.interface
 import zope.interface.adapter
@@ -57,7 +58,23 @@
                 yield name, util
 
 
+    def _updateAdaptersFromLocalData(self, adapters):
+        LocalAdapterService._updateAdaptersFromLocalData(self, adapters)
+        
+        for required, stacks in self.stacks.iteritems():
+            if required is None:
+                required = Default
+            radapters = adapters.get(required)
 
+            for key, stack in stacks.iteritems():
+                registration = stack.active()
+                if registration is not None:
+                    key = True, key[1], '', key[3]
+                    radapters[key] = radapters.get(key, ()) + (
+                        removeAllProxies(registration.factory), )
+
+
+
 class UtilityRegistration(ComponentRegistration):
     """Utility component registration for persistent components
 

Modified: Zope3/trunk/src/zope/component/__init__.py
===================================================================
--- Zope3/trunk/src/zope/component/__init__.py	2004-05-23 16:31:13 UTC (rev 24907)
+++ Zope3/trunk/src/zope/component/__init__.py	2004-05-23 16:57:51 UTC (rev 24908)
@@ -134,6 +134,12 @@
                         " component API change.")
     return getService(Utilities, context).getUtilitiesFor(interface)
 
+
+def getAllUtilitiesRegisteredFor(interface, context=None):
+    return getService(Utilities, context
+                      ).getAllUtilitiesRegisteredFor(interface)
+
+
 # Adapter service
 
 def getAdapter(object, interface, name='', context=None):

Modified: Zope3/trunk/src/zope/component/interfaces.py
===================================================================
--- Zope3/trunk/src/zope/component/interfaces.py	2004-05-23 16:31:13 UTC (rev 24907)
+++ Zope3/trunk/src/zope/component/interfaces.py	2004-05-23 16:57:51 UTC (rev 24908)
@@ -95,6 +95,15 @@
         An iterable of utility name-value pairs is returned.
         """
 
+    def getAllUtilitiesRegisteredFor(interface, context=None):
+        """Return all registered utilities for an interface
+
+        This includes overwridden utilities.
+
+        An iterable of utility instances is returned.  No names are
+        returned.
+        """
+
     # Adapter service
 
     def getAdapter(object, interface, context=None):
@@ -456,7 +465,16 @@
         Returns an iterable of name-utility pairs.
         """
 
+    def getAllUtilitiesRegisteredFor(interface):
+        """Return all registered utilities for an interface
 
+        This includes overwridden utilities.
+
+        An iterable of utility instances is returned.  No names are
+        returned.
+        """
+
+
 class IContextDependent(Interface):
     """Components implementing this interface must have a context component.
 

Modified: Zope3/trunk/src/zope/component/tests/test_api.py
===================================================================
--- Zope3/trunk/src/zope/component/tests/test_api.py	2004-05-23 16:31:13 UTC (rev 24907)
+++ Zope3/trunk/src/zope/component/tests/test_api.py	2004-05-23 16:57:51 UTC (rev 24908)
@@ -14,6 +14,7 @@
 
 import unittest
 
+from zope import component
 from zope.component import servicenames
 from zope.component import getAdapter, queryAdapter
 from zope.component import getNamedAdapter, queryNamedAdapter
@@ -304,6 +305,32 @@
         getService(None, 'Utilities').provideUtility(I2, comp, 'test')
         self.assertEquals(id(getUtility(I2, 'test', ob)), id(comp))
 
+    def test_getAllUtilitiesRegisteredFor(self):
+        class I21(I2):
+            pass
+        class Comp21(Comp):
+            implements(I21)
+        
+        compbob = Comp('bob')
+        comp21 = Comp21('21')
+        comp21bob = Comp21('21bob')
+        
+        getService(None, 'Utilities').provideUtility(I2, comp)
+        getService(None, 'Utilities').provideUtility(I21, comp21)
+        getService(None, 'Utilities').provideUtility(I2, compbob, 'bob')
+        getService(None, 'Utilities').provideUtility(I21, comp21bob, 'bob')
+
+        comps = [comp, compbob, comp21, comp21bob]
+        comps.sort()
+
+        uts = list(component.getUtilitiesFor(I2))
+        uts.sort()
+        self.assertEqual(uts, [('', comp), ('bob', compbob)])
+
+        uts = list(component.getAllUtilitiesRegisteredFor(I2))
+        uts.sort()
+        self.assertEqual(uts, comps)        
+
     def testView(self):
         from zope.component import getView, queryView, getService
         from zope.component.exceptions import ComponentLookupError

Modified: Zope3/trunk/src/zope/component/tests/test_utilityservice.py
===================================================================
--- Zope3/trunk/src/zope/component/tests/test_utilityservice.py	2004-05-23 16:31:13 UTC (rev 24907)
+++ Zope3/trunk/src/zope/component/tests/test_utilityservice.py	2004-05-23 16:57:51 UTC (rev 24908)
@@ -28,6 +28,9 @@
 class IDummyUtility(Interface):
     pass
 
+class IDummerUtility(IDummyUtility):
+    pass
+
 class DummyUtility:
     __name__ = 'DummyUtility'
     implements(IDummyUtility)
@@ -39,7 +42,13 @@
     def __len__(self):
         return 0
 
+class DummerUtility:
+    __name__ = 'DummerUtility'
+    implements(IDummerUtility)
+
+
 dummyUtility = DummyUtility()
+dummerUtility = DummerUtility()
 dummyUtility2 = DummyUtility2()
 
 class Test(TestCase, CleanUp):
@@ -83,7 +92,59 @@
             map(str, us.registrations()),
             ["UtilityRegistration('IDummyUtility', '', 'DummyUtility', '')"])
 
+    def testOverrides(self):
+        us = getService(None, Utilities)
 
+        # fail if nothing registered:
+        self.assertRaises(
+            ComponentLookupError, getUtility, IDummyUtility)
+
+        # set and retiev dummy
+        us.provideUtility(IDummyUtility, dummyUtility)
+        self.assertEqual(getUtility(IDummyUtility), dummyUtility)
+
+        # dummer overrides
+        us.provideUtility(IDummerUtility, dummerUtility)
+        self.assertEqual(getUtility(IDummerUtility), dummerUtility)
+
+        # But not if we ask for dummy
+        self.assertEqual(getUtility(IDummyUtility), dummyUtility)
+
+        # same for named:
+        self.assertRaises(
+            ComponentLookupError, getUtility, IDummyUtility, 'bob')
+        us.provideUtility(IDummyUtility, dummyUtility, 'bob')
+        self.assertEqual(getUtility(IDummyUtility), dummyUtility, 'bob')
+        us.provideUtility(IDummerUtility, dummerUtility, 'bob')
+        self.assertEqual(getUtility(IDummerUtility), dummerUtility, 'bob')
+        self.assertEqual(getUtility(IDummyUtility), dummyUtility, 'bob')
+
+        # getUtilitiesFor doesn the right thing:
+        uts = list(us.getUtilitiesFor(IDummyUtility))
+        uts.sort()
+        self.assertEqual(uts, [('', dummyUtility), ('bob', dummyUtility)])
+        uts = list(us.getUtilitiesFor(IDummerUtility))
+        uts.sort()
+        self.assertEqual(uts, [('', dummerUtility), ('bob', dummerUtility)])
+
+        return us
+
+    def test_getAllUtilitiesRegisteredFor(self):
+        us = self.testOverrides()
+
+        # getAllUtilitiesRegisteredFor includes overridden
+
+        uts = list(us.getAllUtilitiesRegisteredFor(IDummerUtility))
+        self.assertEqual(uts, [dummerUtility, dummerUtility])
+
+        uts = list(us.getAllUtilitiesRegisteredFor(IDummyUtility))
+        uts.remove(dummyUtility)
+        uts.remove(dummyUtility)
+        uts.remove(dummerUtility)
+        uts.remove(dummerUtility)
+        self.assertEqual(uts, [])
+        
+
 def test_suite():
     return makeSuite(Test)
 

Modified: Zope3/trunk/src/zope/component/utility.py
===================================================================
--- Zope3/trunk/src/zope/component/utility.py	2004-05-23 16:31:13 UTC (rev 24907)
+++ Zope3/trunk/src/zope/component/utility.py	2004-05-23 16:57:51 UTC (rev 24908)
@@ -58,6 +58,8 @@
             for item in byname.iteritems():
                 yield item
 
+    def getAllUtilitiesRegisteredFor(self, interface):
+        return iter(self._null.get(('s', interface), ()))
 
 class GlobalUtilityService(UtilityService, GlobalService):
 
@@ -75,6 +77,9 @@
 
         self.register((), providedInterface, name, component)
 
+        # Also subscribe to support getAllUtilitiesRegisteredFor:
+        self.subscribe((), providedInterface, component)
+
         self._registrations[(providedInterface, name)] = UtilityRegistration(
             providedInterface, name, component, info)
 




More information about the Zope3-Checkins mailing list