[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