Zope Lifecycle Events
Zope.lifecycleevent provides a standard set of event objects and convenience functions for describing the lifecycle of objects within a Zope application or any Python system using `zope.event`. This includes events for object creation, modification, addition, removal, and copying. The library is currently at version 6.0 and actively maintained, with new minor versions typically released every 2-6 months and major versions every 2-3 years, aligning with the broader Zope ecosystem.
Common errors
-
AttributeError: module 'pkg_resources' has no attribute 'declare_namespace'
cause This error typically occurs when `zope.lifecycleevent` (or other Zope packages in version 6.x) is installed in an environment using an outdated `setuptools` or build system (like `zc.buildout` prior to version 5) that still expects the `pkg_resources` API for namespace package declarations. Version 6.x migrated to PEP 420 native namespaces.fixUpgrade `setuptools` to its latest version (`pip install --upgrade setuptools`) and ensure your build tools (e.g., `zc.buildout`) are also updated to versions compatible with PEP 420 namespaces (e.g., `zc.buildout >= 5`). -
TypeError: created() missing 1 required positional argument: 'object'
cause You are calling a `zope.lifecycleevent` convenience function (like `created`, `modified`, `added`, etc.) without providing the required `object` argument, which is the entity the event pertains to.fixAlways pass the target object as the first argument to the lifecycle event functions. For example, `created(my_object)` instead of `created()`. -
Events are dispatched but nothing happens / No handlers seem to be registered.
cause `zope.lifecycleevent` dispatches events, but it does not automatically register any handlers to respond to them. If no subscribers are configured to listen for these events, they will be sent but will not trigger any application logic.fixYou must explicitly register event subscribers. In a Zope/Plone application, this is typically done using ZCML configuration (e.g., `<subscriber for="some.interface zope.lifecycleevent.IObjectCreatedEvent" handler=".my_module.my_handler" />`). For simpler cases or in non-Zope environments, you might use `zope.component.provideHandler` with `zope.event.subscribers`.
Warnings
- breaking Version 6.0 of `zope.lifecycleevent` replaced `pkg_resources` namespace handling with PEP 420 native namespaces.
- breaking `zope.lifecycleevent` dropped support for older Python versions in recent major and minor releases.
- gotcha Zope's event system (via `zope.event`) does not guarantee subscriber call order, nor does it allow event cancellation or return values from handlers. Exceptions in a handler will stop further processing.
- gotcha While you can manually instantiate event objects (e.g., `ObjectCreatedEvent`) and dispatch them via `zope.event.notify()`, the documentation strongly recommends using the high-level convenience functions (`created()`, `modified()`, etc.).
Install
-
pip install zope.lifecycleevent
Imports
- created
from zope.lifecycleevent import created
- modified
from zope.lifecycleevent import modified
- added
from zope.lifecycleevent import added
- removed
from zope.lifecycleevent import removed
- copied
from zope.lifecycleevent import copied
- Attributes
from zope.lifecycleevent import Attributes
- ObjectCreatedEvent
from zope.lifecycleevent import ObjectCreatedEvent
Quickstart
from zope.lifecycleevent import created, modified, Attributes
class Document:
def __init__(self, title, content):
self.title = title
self.content = content
def update(self, new_content):
old_content = self.content
self.content = new_content
# Example of sending a modified event with attribute description
# In a real app, you'd likely define an IFile interface for 'content'
modified(self, Attributes(None, 'content'))
print(f"Document '{self.title}' content updated and modified event sent.")
# Create an object and send a creation event
doc = Document("My First Doc", "Initial content.")
created(doc)
print(f"Document '{doc.title}' created and event sent.")
# Modify the object and send a modification event
doc.update("New updated content.")
# Note: To actually *handle* these events, you would need to set up
# subscribers using zope.event.notify and zope.component.provideHandler (not shown here).