Pyramid and Traversal

There has been a lot of discussion in the Pylons/Pyramid community about the concept of traversal.  Some people, when faced with traversal for the first time, get confused and want it removed from Pyramid.  They want Pyramid to support only routes, a different way of achieving a similar goal.

Personally, I think traversal is simpler and more powerful than routes.  Conceptually, traversal is simply an interpretation of path segments as item lookup: the URL path “/spam/eggs/ham” is interpreted in Python as “root[‘spam’][‘eggs’][‘ham’]”.  The root object is some object with a __getitem__ method; root.__getitem__(‘spam’) returns some object which has its own __getitem__ method, and so on.  If __getitem__ raises a KeyError, then Pyramid generates an HTTP 404 error (which you can customize).

The objects along the path are often persistent, but there is no reason they have to be.  Pyramid only requires __getitem__.  Well, actually, they should also have __parent__ and __name__ attributes if you want Pyramid to generate correct URLs for you.  WingCash, which will soon use Pyramid, uses traversal over non-persistent objects that only survive for one request.

Routes, on the other hand, requires a mini-language (similar to regular expressions) and iteration over possible path interpretations.  Expanding the model requires changing the central list of all possible routes.  Routes limits the complexity of the model, while traversal allows arbitrarily complex models.

Traversal is one of the best ideas from the Zope world.  Traversal was painful to do correctly in Zope, yet we still loved it because it allowed us to expand web applications organically.  I am very glad that Pyramid has simplified traversal and made the mechanism easily accessible.  I think traversal is a major ingredient that led to the success of Plone.