[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/Traversing - Namespaces.py:1.5 SkinNamespace.py:1.2 Traverser.py:1.4

Jim Fulton jim@zope.com
Sat, 13 Jul 2002 10:19:07 -0400


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

Modified Files:
	Namespaces.py SkinNamespace.py Traverser.py 
Log Message:
Fixed bug in context management when uri segments that produce only
side effects (e.g. ++skin++ZopeTop) are used.

Fixed up absolute url bread crumbs to not show side-effect steps in
bread crumbs, while retaining them in the breadcrumb urls.

Refactored side-effect handling slightly (changed context data names)
in absolute url and physical path code.

Added tests for side effect handling for absolute url, physical path,
and namespace handling code.


=== Zope3/lib/python/Zope/App/Traversing/Namespaces.py 1.4 => 1.5 ===
 """
 
 from Zope.Exceptions import NotFoundError
-from Zope.Proxy.ContextWrapper import ContextWrapper
+from Zope.Proxy.ContextWrapper import ContextWrapper, getWrapperObject
 from Zope.Configuration.Action import Action
 
 _namespace_handlers = {}
@@ -39,11 +39,36 @@
     name -- the original name
     ns -- The namespace
     qname -- The name without any parameters
+
+    The resulting object is returned in the context of the original.
+    This means that the caller should *not* wrap the result.
     """
     
     handler = _namespace_handlers.get(ns)
     if handler is None:
         raise NotFoundError(name)
-    new = ContextWrapper(handler(qname, parameters, name, object, request),
-                         object, name=name)
+
+    new = handler(qname, parameters, name, object, request)
+    if new is object:    
+        # The handler had a side effect only and didn't look up a
+        # different object.  We want to retain the side-effect name
+        # for things like URLs.
+
+        # But wait, there's more. The object may be wrapped. If the
+        # object is already wrapped and we return the object in the
+        # context of itself, the containment context will be wrong,
+        # because the inner wrapper will be the original object, so
+        # our added layer with the name we want to preserve will be
+        # ignored when searching containment.
+        
+        # For this reason, we'll remove a layer of wrapping from new
+        # before we put it in context.
+
+        new = getWrapperObject(new)
+        
+        new = ContextWrapper(new, object, name='.', side_effect_name=name)
+
+    else:
+        new = ContextWrapper(new, object, name=name)
+
     return new


=== Zope3/lib/python/Zope/App/Traversing/SkinNamespace.py 1.1 => 1.2 ===
 from Exceptions import UnexpectedParameters
 from Zope.Exceptions import NotFoundError
 
+class NoRequest(NotFoundError):
+    """Atempt to access a presentation component outside of a request context
+    """
+
 def skin(name, parameters, pname, ob, request):
 
     if parameters:
         raise UnexpectedParameters(parameters)
+
+    if not request:
+        raise NoRequest(pname)
 
     request.setViewSkin(name)
 


=== Zope3/lib/python/Zope/App/Traversing/Traverser.py 1.3 => 1.4 ===
                     continue
 
                 if name == '..':
+                    # XXX This doesn't look right. Why fall back to curr?
                     curr = getWrapperContainer(curr) or curr
                     continue