[Zope-Checkins] CVS: Zope3/lib/python/Zope/Publisher - IApplicationRequest.py:1.1.2.3 IApplicationResponse.py:1.1.4.1 IPublicationRequest.py:1.1.2.3 IPublisher.py:1.1.2.3 IPublisherRequest.py:1.1.2.3 IPublisherResponse.py:1.1.2.3 RequestDataProperty.py:1.1.4.1 normal.clb:1.1.4.1 BaseRequest.py:1.1.2.24 BaseResponse.py:1.1.2.9 DefaultPublication.py:1.1.2.10 Exceptions.py:1.1.2.11 IPublication.py:1.1.2.10 Publish.py:1.1.2.14 mapply.py:1.1.2.8 minitest.py:1.1.2.7

Jim Fulton jim@zope.com
Tue, 26 Mar 2002 16:26:28 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/Publisher
In directory cvs.zope.org:/tmp/cvs-serv7731/Zope/Publisher

Modified Files:
      Tag: Zope-3x-branch
	BaseRequest.py BaseResponse.py DefaultPublication.py 
	Exceptions.py IPublication.py Publish.py mapply.py minitest.py 
Added Files:
      Tag: Zope-3x-branch
	IApplicationRequest.py IApplicationResponse.py 
	IPublicationRequest.py IPublisher.py IPublisherRequest.py 
	IPublisherResponse.py RequestDataProperty.py normal.clb 
Log Message:
Merged the publication refactoring branch into the main branch.

Also renamed:

  browser_reaverse -> publishTraverse

  browser_default -> browserDefault



=== Zope3/lib/python/Zope/Publisher/IApplicationRequest.py 1.1.2.2 => 1.1.2.3 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+# 
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from Interface.Common.Mapping import IEnumerableMapping
+from Interface.Attribute import Attribute
+
+class IApplicationRequest(IEnumerableMapping):
+    """Features that support application logic
+    """
+
+    def getBody():
+        """Return the body of the request as a string
+        """
+        
+
+    def getBodyFile():
+        """Return the body of the request as a file
+        """
+
+    def __getitem__(key):
+        """Return request data
+
+        The only request data are envirnment variables.
+        """
+
+    environment = Attribute(
+        """Request environment data
+
+        This is a read-only mapping from variable name to value.
+        """)
+
+    


=== Added File Zope3/lib/python/Zope/Publisher/IApplicationResponse.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
# 
##############################################################################
"""

Revision information:
$Id: IApplicationResponse.py,v 1.1.4.1 2002/03/26 21:25:56 jim Exp $
"""

from Interface import Interface

class IApplicationResponse(Interface):
    """Features that support application logic
    """

    def write(string):
        """Output a string to the response body.
        """


=== Zope3/lib/python/Zope/Publisher/IPublicationRequest.py 1.1.2.2 => 1.1.2.3 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+# 
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from Zope.ComponentArchitecture.IViewService import IViewRequest
+
+class IPublicationRequest(IViewRequest):
+    """Interface provided by requests to IPublication objects
+    """
+
+    def getResponse():
+        """Return the request's response object
+
+        Return an IPublisherResponse for the request.
+        """
+
+    def close():
+        """Release resources held by the request.
+        """
+
+    def hold(object):
+        """Hold a reference to an object until the request is closed
+        """
+
+    def getTraversalStack():
+        """Return the request traversal stack
+
+        This is a sequence of steps to traverse in reverse order. They
+        will be traversed from last to first.
+        """
+
+    def setTraversalStack(stack):
+        """Change the traversal stack.
+
+        See getTraversalStack.
+        """
+        
+    def getPositionalArguments():
+        """Return the positional arguments given to the request.
+        """
+        
+    def setViewSkin(skin):
+        """Set the skin to be used for the request.
+
+        It's up to the publication object to decide this.
+        """
+
+


=== Zope3/lib/python/Zope/Publisher/IPublisher.py 1.1.2.2 => 1.1.2.3 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+# 
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from Interface import Interface
+
+def IPublisher(Interface):
+
+    def publish(request):
+        """Publish a request
+
+        The request must be an IPublisherRequest.
+        """
+
+    


=== Zope3/lib/python/Zope/Publisher/IPublisherRequest.py 1.1.2.2 => 1.1.2.3 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+# 
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from IPublicationRequest import IPublicationRequest
+
+class IPublisherRequest(IPublicationRequest):
+    """Request interface use by the publisher
+
+    The responsability of requests is to encapsulate protocol
+    specific details, especially wrt request inputs.
+
+    Request objects also serve as "context" objects. providing
+    construction of and access to responses and storage of publication
+    objects. 
+    
+    """
+
+    def supportsRetry():
+        """Check whether the request supports retry
+
+        Return a boolean value indicating whether the request can be retried.
+        """
+
+    def retry():
+        """Return a retry request
+
+        Return a request suitable for repeating the publication attempt.
+        """
+
+    def getPublication():
+        """Return the requets's publication object
+
+        The publication object, an IRequestPublication provides
+        application-specific functionality hooks.
+        """
+
+    def setPublication(publication):
+        """Set the requets's publication object
+        """
+    
+    def traverse(object):
+        """Traverse from the given object to the published object
+
+        The published object is returned.
+
+        The following hook methods on the publication will be called:
+
+          - callTraversalHooks is called before each step and after
+            the last step.
+
+          - traverseName to actually do a single traversal
+          
+        """
+
+    def processInputs():
+        """Do any input processing that needs to bve done before traversing
+
+        This is done after construction to allow the publisher to
+        handle errors that arise.
+        """


=== Zope3/lib/python/Zope/Publisher/IPublisherResponse.py 1.1.2.2 => 1.1.2.3 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+# 
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from Interface import Interface
+
+class IPublisherResponse(Interface):
+    """Interface used by the publsher
+    """
+
+    def setBody(result):
+        """Set's the response result value.
+        """
+
+    def handleException(exc_info):
+        """Handle an otherwise unhandled exception.
+
+        The handling of the exception is expected to effect the reponse body.
+        """
+        # XXX ZopePublication seems to call this, so maybe this should be
+        # in an IPublicationResponse interface, but maybe this will change,
+        # so we'll apply YAGNI for now.
+
+    def outputBody():
+        """Output the response to the client
+        """
+        
+    def retry():
+        """Return a retry response
+
+        Return a response suitable for repeating the publication attempt.
+        """


=== Added File Zope3/lib/python/Zope/Publisher/RequestDataProperty.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
# 
##############################################################################
"""

Revision information:
$Id: RequestDataProperty.py,v 1.1.4.1 2002/03/26 21:25:57 jim Exp $
"""

class RequestDataGetter(object):

    def __init__(self, request):
        self.__get = getattr(request, self._gettrname)

    def __getitem__(self, name):
        return self.__get(name)

    def get(self, name, default=None):
        return self.__get(name, default)

class RequestDataMapper(object):

    def __init__(self, request):
        self.__map = getattr(request, self._mapname)

    def __getitem__(self, name):
        return self.__map[name]

    def get(self, name, default=None):
        return self.__map.get(name, default)

    def keys(self): return self.__map.keys()
    def items(self): return self.__map.items()
    def values(self): return self.__map.values()
    def __len__(self): return len(self.__map)

class RequestDataProperty(object):

    def __init__(self, gettr_class):
        self.__gettr_class = gettr_class

    def __get__(self, request, rclass=None):
        if request is not None:
            return self.__gettr_class(request)

    def __set__(*args):
        raise AttributeError, 'Unassignable attribute'


=== Added File Zope3/lib/python/Zope/Publisher/normal.clb ===
Publisher framework base collaboration 

  Participants:

    publisher:IPublisher

    request:IPublisherRequest

    response:IPublicationResponse = request.getResponse()

    publication:IPublication = request.getPublication()


  Values:

    root 
        "the top-level object"

    foo
        "an object obtaines by traversing the root with 'foo'"

    bar
        "an object obtaines by traversing the root with 'bar'"

    result
        "The result of calling bar"


  Scenario: Normal, path = foo/bar
     "Show normal publishing of a simple path without errors"

    publisher.publish(request)

        request.processInputs()

        publication.beforeTraversal(request) 

        publication.getApplication(request)
           "Get the root object to be traversed"

        request.traverse(root)

            publication.callTraversalHooks(request, root)
                '''Call any "before traversal step" hooks. These hooks
                should be called before traversing an object for the
                first time. If the same object is traversed more than
                once, the hook will still only be called the first
                time.

                The last constraint is probably important to get
                virtual host semantics rigfht. :)
                ''' 
            
            publication.traverseName(request, root, 'foo')

            publication.callTraversalHooks(request, foo)
                       
            publication.traverseName(request, foo, 'bar')
            
            return bar
            
        publication.afterTraversal(request, bar)

        publication.callObject(request, bar)

            return result

        response.setBody(result)

        publication.afterCall(request)

        response.outputBody()

        request.close()


  Scenario: Error during application call, path = foo
      "Show what heppens when the main application code raises an error"

    publisher.publish(request)

        request.processInputs()

        publication.beforeTraversal(request) 

        publication.getApplication(request)

        request.traverse(root)

            publication.callTraversalHooks(request, root)
            
            publication.traverseName(request, root, 'foo')
            
            return foo

        publication.afterTraversal(request, foo)

        publication.callObject(request, foo)

            raise AttributeError, 'spam'


        publication.handleException()

        response.outputBody()

        request.close()



=== Zope3/lib/python/Zope/Publisher/BaseRequest.py 1.1.2.23 => 1.1.2.24 === (437/537 lines abridged)
 #
-# Copyright (c) 2001 Zope Corporation and Contributors.  All Rights Reserved.
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
 # 
 # This software is subject to the provisions of the Zope Public License,
-# Version 1.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
+# FOR A PARTICULAR PURPOSE
+# 
 ##############################################################################
 """
 
@@ -17,19 +19,22 @@
 from urllib import quote
 from cgi import escape
 from types import StringType
-from Zope.ComponentArchitecture.IViewService import IViewRequest
+from BaseResponse import BaseResponse
+from IApplicationRequest import IApplicationRequest
+from IPublisherRequest import IPublisherRequest
+from IPublicationRequest import IPublicationRequest
+from RequestDataProperty import RequestDataProperty, RequestDataMapper
 
-def pc_quote(s):
-    """
-    URL-quotes only the characters not allowed in the path
-    component of a URL.  See RFC 2396 Section 3.3.
+class IRequest(IPublisherRequest, IPublicationRequest, IApplicationRequest):
+    """The basic request contract
     """
-    return quote(s, "/:@&=+$,;")
 
+_marker = object()
 
-_marker = []
+class RequestEnvironment(RequestDataMapper):
+    _mapname = '_environ'
 
-class BaseRequest:
+class BaseRequest(object):
     """Represents a publishing request.
     
     This object provides access to request data. Request data may
@@ -42,76 +47,155 @@
     collection of variable to value mappings.

[-=- -=- -=- 437 lines omitted -=- -=- -=-]

-        Holds a reference to an object to delay its destruction until mine
-        """
-        self._held = self._held + (object,)
+    def _createResponse(self, outstream):
+        # Should be overridden by subclasses
+        return BaseResponse(outstream)
 
+    def __nonzero__(self):
+        # This is here to avoid calling __len__ for boolean tests
+        return 1
 
-    # Implementation methods for interface
-    # Zope.ComponentArchitecture.IViewService.IViewRequest
+    def __str__(self):
+        L1 = self.items()
+        L1.sort()
+        return "\n".join(map(lambda item: "%s:\t%s" % item, L1))
 
-    # Base classes might provide different attributes for this
+    def __repr__(self):
+        # Returns a *short* string.
+        return '<%s instance at 0x%x, URL=%s>' % (
+            str(self.__class__), id(self), `self.URL`)
 
-    _viewskin = ''
-    _viewtype = None
-    
-    def getViewSkin(self):
-        '''See interface IViewRequest'''
 
-        return self._viewskin
 
 
-    def setViewSkin(self, skin):
-        ''' add the view skin '''
- 
-        self._viewskin = skin
 
 
-    def getViewType(self):
-        '''See interface IViewRequest'''
 
-        return self._viewtype
 
 
-    def setViewType(self, viewtype):
-        ''' set the view type '''
 
-        self._viewtype = viewtype
 


=== Zope3/lib/python/Zope/Publisher/BaseResponse.py 1.1.2.8 => 1.1.2.9 ===
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
 # 
 # This software is subject to the provisions of the Zope Public License,
-# Version 1.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-
+# FOR A PARTICULAR PURPOSE
+# 
+##############################################################################
 '''Response Output formatter
 
-$Id$'''
-__version__='$Revision$'[11:-2]
+$Id$
+'''
 
-from Exceptions import Unauthorized
+import traceback
+from IPublisherResponse import IPublisherResponse
+from IApplicationResponse import IApplicationResponse
+
+class IResponse(IPublisherResponse, IApplicationResponse):
+    """The basic response contract
+    """
 
-class BaseResponse:
-    """Base Response Class
 
-    What should be here?
+class BaseResponse(object):
+    """Base Response Class
     """
-    debug_mode=None
-    status = None         # The response status (usually an integer)
-    body = ''
-    base = None
-    #_auth=None
-    #_error_format='text/plain'
-    
-    def __init__(self, outstream):
-        self.outstream = outstream
-        self.headers = {}
-        self.cookies = {}
 
-    def setDebugMode(self, d):
-        self.debug_mode = d
+    __slots__ = (
+        '_body',      # The response body
+        '_outstream', # The output stream
+        )
+
+    __implements__ = IResponse
+
     
-    def setStatus(self, status, reason=None):
-        self.status = status
+    def __init__(self, outstream):
+        self._body = ''
+        self._outstream = outstream
 
-    def setHeader(self, name, value):
-        self.headers[name] = value
+    ############################################################
+    # Implementation methods for interface
+    # Zope.Publisher.BaseResponse.IResponse
 
-    __setitem__ = setHeader
+    ######################################
+    # from: Zope.Publisher.IPublisherResponse.IPublisherResponse
 
     def outputBody(self):
-        """
-        Output the response body.
-        """
-        self.outstream.write(str(self))
+        'See Zope.Publisher.IPublisherResponse.IPublisherResponse'
+        self._outstream.write(self._getBody())
 
     def setBody(self, body):
-        self.body = body
-
-    def setBase(self,base):
-        'Sets the base URL for the returned document.'
-        self.base=base
-
-    def getBase(self):
-        ' return the base url '
-        return self.base
-
-    def getStatus(self):
-        'Returns the current HTTP status code as an integer. '
-        return self.status
-
-    def setCookie(self,name,value,**kw):
-        '''
-        Sets an HTTP cookie on the browser
-
-        The response will include an HTTP header that sets a cookie on
-        cookie-enabled browsers with a key "name" and value
-        "value". This overwrites any previously set value for the
-        cookie in the Response object.
-        '''
-        cookies=self.cookies
-        if cookies.has_key(name):
-            cookie=cookies[name]
-        else: cookie=cookies[name]={}
-        for k, v in kw.items():
-            cookie[k]=v
-        cookie['value']=value
-
-    def getHeader(self, name):
-         '''
-         Gets a header value
-         
-         Returns the value associated with a HTTP return header, or
-         "None" if no such header has been set in the response
-         yet.
-         '''
-         return self.headers.get(name, None)
-
-    def __getitem__(self, name):
-        'Gets the value of an output header'
-        return self.headers[name]
+        'See Zope.Publisher.IPublisherResponse.IPublisherResponse'
+        self._body = body
 
-    def getBody(self):
+    # This method is not part of this interface
+    def _getBody(self):
         'Returns a string representing the currently set body.'
-        return self.body
-
-    def __str__(self):
-        return str(self.body)
-
-    def __repr__(self):
-        return '%s(%s)' % (self.__class__.__name__, `self.body`)
-
-    def flush(self):
-        pass
-
-    def write(self,data):
-        """
-        Implements the stream output interface.
-
-        HTML data may be returned using a stream-oriented interface.
-        This allows the browser to display partial results while
-        computation of a response to proceed.
-
-        The published object should first set any output headers or
-        cookies on the response object.
-
-        Note that published objects must not generate any errors
-        after beginning stream-oriented output. 
-        """
-        self.body = self.body + data
+        return self._body
 
     def handleException(self, exc_info):
-        import traceback
+        'See Zope.Publisher.IPublisherResponse.IPublisherResponse'
         traceback.print_exception(
             exc_info[0], exc_info[1], exc_info[2], 100, self)
 
+    def retry(self):
+        'See Zope.Publisher.IPublisherResponse.IPublisherResponse'
+        return self.__class__(self.outstream)
+
+    ######################################
+    # from: Zope.Publisher.IApplicationResponse.IApplicationResponse
+
+    def write(self, string):
+        'See Zope.Publisher.IApplicationResponse.IApplicationResponse'
+        self._body += string
+
+    #
+    ############################################################


=== Zope3/lib/python/Zope/Publisher/DefaultPublication.py 1.1.2.9 => 1.1.2.10 ===
 
     def beforeTraversal(self, request):
-        pass
+        # Lop off leading and trailing empty names
+        stack = request.getTraversalStack()
+        while stack and not stack[-1]:
+            stack.pop() # toss a trailing empty name
+        while stack and not stack[0]:
+            stack.pop(0) # toss a leading empty name
+        request.setTraversalStack(stack)
 
     def getApplication(self, request):
         return self.app
@@ -41,24 +47,36 @@
                     TypeError, AttributeError):
                 raise NotFound(ob, name, request)
         if self.require_docstrings and not getattr(subob, '__doc__', None):
-            raise DebugError(subob, 'Missing or empty doc string at: %s' %
-                             request.getURL())
+            raise DebugError(subob, 'Missing or empty doc string')
         return subob
 
     def getDefaultTraversal(self, request, ob):
-        return ob, None
+        return ob, ()
 
     def afterTraversal(self, request, ob):
         pass
 
     def callObject(self, request, ob):
-        return mapply(ob, request.args, request)
+        return mapply(ob, request.getPositionalArguments(), request)
 
     def afterCall(self, request):
         pass
 
     def handleException(self, request, exc_info, retry_allowed=1):
         # Let the response handle it as best it can.
-        response = request.response
+        response = request.getResponse()
         response.handleException(exc_info)
 
+
+class TestPublication(DefaultPublication):
+    
+    def traverseName(self, request, ob, name, check_auth=1):
+        if hasattr(ob, name):
+            subob = getattr(ob, name)
+        else:
+            try:
+                subob = ob[name]
+            except (KeyError, IndexError,
+                    TypeError, AttributeError):
+                raise NotFound(ob, name, request)
+        return subob


=== Zope3/lib/python/Zope/Publisher/Exceptions.py 1.1.2.10 => 1.1.2.11 ===
         self.ob = ob
         self.name = name
-        if request is not None:
-            url = request.getEffectiveURL()
-        else:
-            url = None
-        self.url = url
 
     def getObject(self):
         return self.ob
@@ -41,10 +36,7 @@
         return self.name
 
     def __str__(self):
-        if self.url:
-            return self.url
-        else:
-            return 'Object: %s, name: %s' % (`self.ob`, `self.name`)
+        return 'Object: %s, name: %s' % (`self.ob`, `self.name`)
 
 
 class DebugError (TraversalException):


=== Zope3/lib/python/Zope/Publisher/IPublication.py 1.1.2.9 => 1.1.2.10 ===
 
 class IPublication (Interface):
-    """
-    Object publication framework.
+    """Object publication framework.
+
+    The responsibility of publication objects is to provide
+    application hooks for the publishing process. This allows
+    application-specific tasks, such as connecting to databases,
+    managing transactions, and setting security contexts to be invoked
+    during the publishing process.
+
     """
     # The order of the hooks mostly corresponds with the order in which
     # they are invoked.
@@ -39,36 +45,31 @@
         Returns the subobject.
         """
 
-    def getDefaultTraversal(request, ob):
-        """
-        Allows a default view to be added to traversal.
-        Returns (ob, steps_reversed).
-        """
-
     def afterTraversal(request, ob):
-        """
-        Post-traversal hook.
+        """Post-traversal hook.
         """
 
     def callObject(request, ob):
-        """
-        Calls the object, returning the result as a string.
+        """Call the object, returning the result.
+        
         For GET/POST this means calling it, but for other methods
         (including those of WebDAV and FTP) this might mean invoking
         a method of an adapter.
         """
 
     def afterCall(request):
-        """
-        Post-callObject hook (if it was successful).
+        """Post-callObject hook (if it was successful).
         """
 
     def handleException(request, exc_info, retry_allowed=1):
-        """
+        """Handle an exception
+        
         Either:
-        - sets the body of request.response,
+        - sets the body of the response, request.getResponse(), or
         - raises a Retry exception, or
         - throws another exception, which is a Bad Thing.
-        Returns the response object.
+
+        Note that this method should not leak, which means that
+        exc_info must be set to some other value before exiting the method.
         """
 


=== Zope3/lib/python/Zope/Publisher/Publish.py 1.1.2.13 => 1.1.2.14 ===
     - Some other exception if handleException() raised an exception.
     """
-    publication = None
-    response = request.response
+    
+    publication = request.getPublication()
+    response = request.getResponse()
 
     try:
         request.processInputs()
-        publication = request.getPublication()
         publication.beforeTraversal(request)
 
         root_object = publication.getApplication(request)
-        object = request.traverse(publication, root_object)
+        object = request.traverse(root_object)
         publication.afterTraversal(request, object)
 
         result = publication.callObject(request, object)
@@ -41,16 +41,7 @@
 
         publication.afterCall(request)
     except:
-        handleException(request, publication, sys.exc_info(), 1)
-
-
-
-def handleException(request, publication, exc_info, allow_retry=1):
-    if publication is not None:
-        publication.handleException(request, exc_info, allow_retry)
-    else:
-        request.response.handleException(exc_info)
-
+        publication.handleException(request, sys.exc_info(), 1)
 
 
 def publish(request):
@@ -62,8 +53,8 @@
                     executeRequest(request)
                     # Successful.
                     break
-                except Retry, v:
-                    if request.supports_retry():
+                except Retry, retryException:
+                    if request.supportsRetry():
                         # Create a copy of the request and use it.
                         newrequest = request.retry()
                         request.close()
@@ -71,21 +62,19 @@
                     else:
                         # Output the original exception.
                         publication = request.getPublication()
-                        handleException(request, publication,
-                                        v.getOriginalException(), 0)
+                        publication.handleException(
+                            request, retryException.getOriginalException(), 0)
                         break
             except:
                 # Bad exception handler or retry method.
                 # Re-raise after outputting the response.
                 to_raise = sys.exc_info()
-                request.response.setStatus(500) # Try to indicate an error.
                 break
 
-        response = request.response
+        response = request.getResponse()
         response.outputBody()
         if to_raise is not None:
             raise to_raise[0], to_raise[1], to_raise[2]
-        return response.getStatus()
 
     finally:
         to_raise = None  # Avoid circ. ref.


=== Zope3/lib/python/Zope/Publisher/mapply.py 1.1.2.7 => 1.1.2.8 ===
     return unwrapped, wrapperCount
 
-def mapply(object, positional=(), keyword={}, call=apply):
+def mapply(object, positional=(), request={}, call=apply):
     __traceback_info__ = object
     unwrapped, wrapperCount = unwrapMethod( object )
     code = unwrapped.func_code
@@ -66,7 +66,7 @@
     else:
         args = []
 
-    get = keyword.get
+    get = request.get
     if defaults:
         nrequired = len(names) - (len(defaults))
     else:
@@ -75,10 +75,13 @@
         name = names[index]
         v = get(name, _marker)
         if v is _marker:
-            if index < nrequired:
+            if name == 'REQUEST':
+                v = request
+            elif index < nrequired:
                 raise TypeError, 'Missing argument to %s(): %s' % (
                     getattr(unwrapped, '__name__', repr(object)), name)
-            else: v = defaults[index-nrequired]
+            else:
+                v = defaults[index-nrequired]
         args.append(v)
 
     args = tuple(args)


=== Zope3/lib/python/Zope/Publisher/minitest.py 1.1.2.6 => 1.1.2.7 ===
 class c:
     " "
-    def __call__(self, URL):
-        return 'You invoked URL %s\n' % URL
+    def __call__(self, REQUEST):
+        return 'You invoked URL %s\n' % REQUEST.URL
 
 ob = c()
 ob.x = c()