[Zope3-dev] revisiting IResult (for in-Zope pipelining)

Gary Poster gary at zope.com
Sun Apr 15 21:51:27 EDT 2007


The work that Jim Washington and David Pratt have started recently to  
make lxml an XHTML generator/ZPT replacement [#1]_ has really excited  
me.  It would be *great* with in-Zope pipelines [#2]_.

IResult (zope/publisher/http.py, about line 600) has been the hidden,  
private, don't-use-it-because-it's-going-away tool with which you can  
build pipelines since before Dec. 2005 [#3]_  I know at least a  
couple of people who haven't explored the idea of using it for a  
pipeline, despite interest, simply because the IResult interface was  
private.

Can we quickly figure out a reasonable way to make the new, improved  
interface ready for 3.4?  With it there, competitively or  
collaboratively, we can write in-Zope pipelines as standalone  
packages, and "may the best pipeline win".  Or we can just get a  
start with some small, cool lxml stuff.

So what should the public API be?

Here are two emails Jim (Fulton) wrote, corresponding with Phillipp,  
about the thoughts behind IResult.

http://mail.zope.org/pipermail/zope3-dev/2005-December/016778.html
http://mail.zope.org/pipermail/zope3-dev/2005-December/016796.html

Talking with Jim about this recently, he effectively questioned this  
bullet point from the first email I linked:

"""
- An adapter may need to affect outut headers, so IResult
    needed to provide header data.
"""

His question was, since the adaptation gets the request, why not just  
have the adapter set the headers directly with request.response?

That line of reasoning appeals to me.

So, as a strawman, I propose that we make a public interface in  
zope.publisher called IResult:

class IResult(zope.interface.Interface):
	"""An iterable that provides the body data of the response.
         For simplicity, an adapter to this interface may in fact return
         any iterable, without needing to strictly have the iterable
         provide IResult."""

(I don't define __iter__ explicitly since I've been reminded too many  
times that __getitem__ is still a workable iteration protocol.)

Then we look up the IRequest using the same multiadaptation of  
(result, request) we have now, which makes it possible to set headers  
in the adapter if desired.

An IResult adapter could then be as simple as this:

@zope.interface.implementer(zope.publisher.interfaces.http.IResult)
@zope.component.adapter(
     SomeCoolLXMLThing,
     zope.pubisher.interfaces.browser.IBrowserRequest)
def postprocessLXML(lxml, request):
     do_some_cool_transformation(lxml)
     return output_to_html(lxml)

and it might do a bit of request.response.setHeader(...) calls too,  
if appropriate.

We would delete the private IRequest entirely, without deprecation (I  
argue that the warning in the doc string is pretty supportive of this).

The ``zope.publisher.http.HTTPResponse.setResult`` method then looks  
something like this:

     def setResult(self, result):
         if IResult.providedBy(result):
             r = result
         else:
             r = component.queryMultiAdapter((result, self._request),  
IResult)
             if r is None:
                 if isinstance(result, basestring):
                     r = result
                 elif result is None:
                     r = ''
                 else:
                     raise TypeError(
                         'The result should be a string, None, or  
adaptable to IResult.')
             if isinstance(r, basestring):
                 r, headers = self._implicitResult(result)
                 self._headers.update(dict([(k, [v]) for (k, v) in  
headers]))
         self._result = r
         if not self._status_set:
             self.setStatus(200)

Votes?  Alternate suggestions?

Gary


.. [#1] http://cheeseshop.python.org/pypi/zif.xtemplate/0.1

.. [#2] I want views to be able to return lxml structures, and  
widgets to be able to return lxml structures.  I want the publisher  
to have a pipeline to be able to transform the output of a view with  
o-wrap, and zc.resourcelibrary-like postprocessing done right.  I  
want pages to be able to cache their lxml output, while then an o- 
wrap gets personalized/more timely bits for the o-wrap.  And so on.

.. [#3] http://mail.zope.org/pipermail/zope3-dev/2005-December/ 
017236.html


More information about the Zope3-dev mailing list