[Checkins] SVN: Zope3/branches/3.3/ - Fixed ``get/queryNextUtility`` to work with multiple base registries.

Stephan Richter srichter at cosmos.phy.tufts.edu
Tue Sep 26 05:20:10 EDT 2006


Log message for revision 70383:
  - Fixed ``get/queryNextUtility`` to work with multiple base registries.
  

Changed:
  U   Zope3/branches/3.3/doc/CHANGES.txt
  U   Zope3/branches/3.3/src/zope/app/component/README.txt
  U   Zope3/branches/3.3/src/zope/app/component/__init__.py

-=-
Modified: Zope3/branches/3.3/doc/CHANGES.txt
===================================================================
--- Zope3/branches/3.3/doc/CHANGES.txt	2006-09-26 08:56:49 UTC (rev 70382)
+++ Zope3/branches/3.3/doc/CHANGES.txt	2006-09-26 09:20:09 UTC (rev 70383)
@@ -6,6 +6,12 @@
 
   For information on future releases, see ROADMAP.txt.
 
+  Zope 3.3.0c2 (???)
+
+    Bugfixes
+
+      - Fixed ``get/queryNextUtility`` to work with multiple base registries.
+
   Zope 3.3.0c1 (2006/09/12)
 
     Bugfixes

Modified: Zope3/branches/3.3/src/zope/app/component/README.txt
===================================================================
--- Zope3/branches/3.3/src/zope/app/component/README.txt	2006-09-26 08:56:49 UTC (rev 70382)
+++ Zope3/branches/3.3/src/zope/app/component/README.txt	2006-09-26 09:20:09 UTC (rev 70383)
@@ -34,7 +34,7 @@
 
 While the component architecture API provided by `zope.component` is
 sufficient most of the time, there are a couple of functions that are useful
-in the context of multiple sites. 
+in the context of multiple sites.
 
 A very common use case is to get the nearest site manager in a given
 context. Sometimes, however, one wants the next higher-up site manager. First,
@@ -44,7 +44,7 @@
   >>> root = setup.buildSampleFolderTree()
   >>> root_sm = setup.createSiteManager(root)
   >>> folder1_sm = setup.createSiteManager(root['folder1'])
- 
+
 If we ask `folder1` for its nearest site manager, we get
 
   >>> from zope.app import zapi
@@ -85,22 +85,22 @@
   >>> import zope.interface
   >>> class IMyUtility(zope.interface.Interface):
   ...     pass
-  
+
   >>> class MyUtility(object):
   ...     zope.interface.implements(IMyUtility)
   ...     def __init__(self, id):
   ...         self.id = id
   ...     def __repr__(self):
-  ...         return "%s('%s')" %(self.__class__.__name__, self.id)  
+  ...         return "%s('%s')" %(self.__class__.__name__, self.id)
 
-  >>> gutil = MyUtility('global') 
+  >>> gutil = MyUtility('global')
   >>> gsm.registerUtility(gutil, IMyUtility, 'myutil')
 
-  >>> util1 = setup.addUtility(folder1_sm, 'myutil', IMyUtility, 
+  >>> util1 = setup.addUtility(folder1_sm, 'myutil', IMyUtility,
   ...                          MyUtility('one'))
 
   >>> folder1_1_sm = setup.createSiteManager(root['folder1']['folder1_1'])
-  >>> util1_1 = setup.addUtility(folder1_1_sm, 'myutil', IMyUtility, 
+  >>> util1_1 = setup.addUtility(folder1_1_sm, 'myutil', IMyUtility,
   ...                            MyUtility('one-one'))
 
 Now, if we ask `util1_1` for its next available utility and we get
@@ -115,15 +115,35 @@
 
 However, if we ask the global utility for the next one, an error is raised
 
-  >>> component.getNextUtility(gutil, IMyUtility, 
+  >>> component.getNextUtility(gutil, IMyUtility,
   ...                          'myutil') #doctest: +NORMALIZE_WHITESPACE
   Traceback (most recent call last):
-  ...  
-  ComponentLookupError: 
-  No more utilities for <InterfaceClass __builtin__.IMyUtility>, 
+  ...
+  ComponentLookupError:
+  No more utilities for <InterfaceClass __builtin__.IMyUtility>,
   'myutil' have been found.
 
 or you can simply use the `queryNextUtility` and specify a default:
 
   >>> component.queryNextUtility(gutil, IMyUtility, 'myutil', 'default')
   'default'
+
+Let's now ensure that the function also works with multiple registries. First
+we create another base registry:
+
+  >>> from zope.component import registry
+  >>> myregistry = registry.Components()
+
+  >>> custom_util = MyUtility('my_custom_util')
+  >>> myregistry.registerUtility(custom_util, IMyUtility, 'my_custom_util')
+
+Now we add it as a base to the local site manager:
+
+  >>> folder1_sm.__bases__ = (myregistry,) + folder1_sm.__bases__
+
+Both, the ``myregistry`` and global utilities should be available:
+
+  >>> component.queryNextUtility(folder1_sm, IMyUtility, 'my_custom_util')
+  MyUtility('my_custom_util')
+  >>> component.queryNextUtility(folder1_sm, IMyUtility, 'myutil')
+  MyUtility('global')

Modified: Zope3/branches/3.3/src/zope/app/component/__init__.py
===================================================================
--- Zope3/branches/3.3/src/zope/app/component/__init__.py	2006-09-26 08:56:49 UTC (rev 70382)
+++ Zope3/branches/3.3/src/zope/app/component/__init__.py	2006-09-26 09:20:09 UTC (rev 70383)
@@ -63,8 +63,11 @@
 
     Find the next available utility providing `interface` and having the
     specified name. If no utility was found, return the specified `default`
-    value."""    
-    sm = queryNextSiteManager(context)
-    if sm is None:
-        return default
-    return sm.queryUtility(interface, name, default)
+    value."""
+    sm = zope.component.getSiteManager(context)
+    bases = sm.__bases__
+    for base in bases:
+        util = base.queryUtility(interface, name, _marker)
+        if util is not _marker:
+            return util
+    return default



More information about the Checkins mailing list