Zope Traversing

6.0 · active · verified Fri Apr 17

Zope Traversing (current version 6.0) provides a robust and extensible mechanism for resolving paths within an object hierarchy, common in Zope-based applications and web frameworks. It allows developers to define how objects are looked up by name or through adapters, enabling flexible URL dispatching and content navigation. It has a steady release cadence, typically releasing new major versions every few years, with minor releases and bug fixes more frequently.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to define a simple object hierarchy using `ITraversable` and then navigate it using `zope.traversing.api.traverse`. It sets up a root folder containing sub-folders and documents, and shows how to retrieve an item by its path, as well as how `KeyError` (or `zope.traversing.interfaces.NotFound` in more complex setups) is raised for non-existent paths.

from zope.interface import implementer
from zope.traversing.interfaces import ITraversable
from zope.traversing.api import traverse

# Define a simple traversable object (e.g., a Folder)
@implementer(ITraversable)
class Folder:
    def __init__(self, name, parent=None):
        self.__name__ = name
        self.__parent__ = parent
        self.contents = {}

    def __setitem__(self, name, item):
        item.__name__ = name
        item.__parent__ = self
        self.contents[name] = item

    def __getitem__(self, name):
        if name in self.contents:
            return self.contents[name]
        raise KeyError(f"No item named '{name}'")

    def traverse(self, name, furtherPath): # furtherPath is usually ignored for simple dict-like traversal
        # Default traversal: look up in contents
        return self.contents[name]

    def __repr__(self):
        return f"<Folder '{self.__name__}'>"

class Document:
    def __init__(self, name, content="", parent=None):
        self.__name__ = name
        self.__parent__ = parent
        self.content = content

    def __repr__(self):
        return f"<Document '{self.__name__}'>"

# Build a hierarchy
root = Folder('')
products_folder = Folder('products')
root['products'] = products_folder
products_folder['book1'] = Document('book1', "The first book.")
products_folder['book2'] = Document('book2', "The second book.")

# Traverse to an item
try:
    item = traverse(root, 'products/book1')
    print(f"Found item at 'products/book1': {item}")

    # Attempt to traverse to a non-existent item
    non_existent_item = traverse(root, 'products/nonexistent')
    print(f"Found non-existent item: {non_existent_item}") # This line won't be reached
except KeyError as e:
    print(f"Error traversing to 'products/nonexistent': {e} (expected behavior)")

# Traverse to a sub-path within an item if it also implements ITraversable
# (not shown in this basic example for Document, but would work for nested Folders)

view raw JSON →