Zope Location
Zope Location is a small, focused library from the Zope Foundation providing an interface and a default implementation for objects that know their hierarchical position via `__parent__` and `__name__` attributes. It's a foundational component for traversal in many Zope-based applications. The current version is 6.0. It follows the Zope Foundation's release cadence, typically releasing new major versions to drop old Python support or introduce minor enhancements.
Common errors
-
AttributeError: '__parent__'
cause You are attempting to access `obj.__parent__` or `obj.__name__` on a `zope.location.location.Location` instance, but these attributes have not yet been set or initialized.fixEnsure that you explicitly set `obj.__parent__ = parent_obj` and `obj.__name__ = 'child_name'` after creating your located object, or within its `__init__` method. -
TypeError: 'Location' object is not subscriptable
cause You are trying to retrieve a child object from a `zope.location.location.Location` instance using dictionary-like indexing (e.g., `parent_obj['child_name']`). `Location` objects do not implement containment methods by default.fixIf you require your located objects to also function as containers, you must implement the `__getitem__` (and potentially `__setitem__`, `__delitem__`) methods in your custom located class. `zope.location` itself focuses only on the location aspects.
Warnings
- gotcha The `__parent__` and `__name__` attributes of `Location` objects are not automatically populated or managed upon instantiation. They are merely attributes that `zope.location` expects to exist.
- gotcha `zope.location.location.Location` objects are designed for 'locating' themselves within a hierarchy but do not inherently provide container functionality (e.g., dictionary-like `__getitem__` or `__setitem__`).
- breaking Version 6.0 of `zope.location` dropped support for Python 3.8. It now explicitly requires Python 3.9 or newer to run.
Install
-
pip install zope.location
Imports
- Location
from zope.location.location import Location
- ILocation
from zope.location.interfaces import ILocation
- Located
from zope.location.location import Located
Quickstart
from zope.location.location import Location
from zope.location.interfaces import ILocation
# Define a simple located object by subclassing Location
class MyLocatedObject(Location):
def __init__(self, name=None, parent=None, value=None):
# Explicitly set __name__ and __parent__ during initialization
self.__name__ = name
self.__parent__ = parent
self.value = value
# Create a hierarchy of located objects
root = MyLocatedObject(name='', parent=None, value="I am the root")
folder = MyLocatedObject(name='folder', parent=root, value="I am a folder object")
item = MyLocatedObject(name='item', parent=folder, value="I am an item inside the folder")
# Verify that the ILocation interface is provided by these objects
assert ILocation.providedBy(root)
assert ILocation.providedBy(folder)
assert ILocation.providedBy(item)
print(f"Root: {root.value} (name='{root.__name__}', parent={root.__parent__})")
print(f"Folder: {folder.value} (name='{folder.__name__}', parent={folder.__parent__.value})")
print(f"Item: {item.value} (name='{item.__name__}', parent={item.__parent__.value})")
# Demonstrate traversal by accessing parent attributes
print(f"\nAccessing parent from item: {item.__parent__.value}")
print(f"Accessing parent's parent from item: {item.__parent__.__parent__.value}")