repoze.obob Changelog
=====================

0.4 (2008-07-11)
----------------

- Change the contract of ``handle_exception``.  As before, if this
  method exists on a helper, it is called by the publisher when any
  other helper step raises an exception.  However, unlike its contract
  in 0.3, it *must* either raise an exception *or* return a
  three-tuple representing the (status, headers, and body_iter) that
  will be used to send to our WSGI upstream caller.  In particular, it
  is no longer legal to return None from ``handle_exception``.

- ``handle_exception`` is now a required method on helpers.

0.3 (2008-04-16)
----------------

- Allow helpers to have a ``handle_exception`` method.  If this method
  exists on a helper, it is called by the publisher when any other
  helper step raises an exception.   It is called with a single
  argument, which will be a three-tuple, representing the type, value,
  and traceback of the exception that occurred (the result of
  sys.exc_info()).  The ``handle_exception`` method should either
  reraise the exception wholesale (e.g. ``raise t, v, tb``) or raise a
  different exception.  The return value of ``handle_exception`` is
  ignored.  If the helper's ``handle_exception`` returns without
  raising, or the helper has no ``handle_exception`` method, the
  original exception is re-raised by obob.

0.2 (2007-10-22)
----------------

- The traversal algorithm implemented in ``ObobPublisher.__call__`` used
  to be::

     current = root
     for name in helper.path_elements():
         helper.before_traverse(current, name)
         current = helper.traverse(current, name)

  This presumed that the helper knows about all the path elements
  before traversing.  This is sometimes not the case.  To account for
  this, we now assume the helper provides a method named ``next_name``
  in order to allow the helper to compose path elements both before
  and during traversal.  The resulting traversal algorithm is::

     current = root
     while 1:
         helper.before_traverse(current)
         name = helper.next_name()
         if name is None:
             break
         current = helper.traverse(current, name)

  Note that the helper ``before_traverse`` method is no longer passed
  the name (because we don't know any name yet).

  The change to the algorithm is primarily to allow hacks like
  CMFDynamicType's ``__before_publishing_traverse__``, which modifies the
  traversal request name stack to find "alias" names.  This fixes
  breakages evident when publishing Plone through repoze.zope2.

0.1 (2007-10-22)
----------------

- Initial release.
