[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/ComponentArchitecture - hooks.py:1.3

Jim Fulton jim@zope.com
Fri, 12 Jul 2002 18:46:08 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/App/ComponentArchitecture
In directory cvs.zope.org:/tmp/cvs-serv14179/lib/python/Zope/App/ComponentArchitecture

Modified Files:
	hooks.py 
Log Message:
Fixed a bug in getNextService that caused infinite loops if objects
are repeated in the acquisition chain, as they are when special URL
steps like ++skin++ZopeTop are used.


=== Zope3/lib/python/Zope/App/ComponentArchitecture/hooks.py 1.2 => 1.3 ===
     """if the context is a service manager or a placeful service, tries
     to return the next highest service manager"""
 
-    context = getServiceManager_hook(context)
-    if context is serviceManager:
+    # get this service manager
+    sm = getServiceManager_hook(context)
+    if sm is serviceManager:
         raise ComponentLookupError('service manager')
 
-    context=getWrapperContainer(context)
-    while (context and not 
-           IServiceManagerContainer.isImplementedBy(removeAllProxies(context))
+    # get the service manager container, which ought to be the context
+    # contaioner.
+    container = getWrapperContainer(sm)
+
+    # But we're *really* paranoid, so we'll double check.
+    while ((container is not None) and not 
+           IServiceManagerContainer.isImplementedBy(
+                      removeAllProxies(container))
            ):
-        context=getWrapperContainer(context) # we should be
+        container = getWrapperContainer(container) # we should be
+
+    # Now we need to step up so we can look for a service manager above.
+    context = getWrapperContainer(container)
+
+    # But we have to make sure we haven't got the same object..
+    while (context is not None) and (context == container):
+        context = getWrapperContainer(context)
 
-    # able to rely on the first step getting us a
-    # ServiceManagerContainer
-    context=getWrapperContainer(context)
     return getServiceManager_hook(context)