[Zope3-dev] Container interface issues

Jim Fulton jim at zope.com
Wed Sep 10 09:59:01 EDT 2003


In the parentgeddon proposal:

   http://dev.zope.org/Zope3/ParentGeddon

I proposed that application code, rather than containers, be
responsible for generating events and calling necessary hooks when
adding or removing objects.  This is necessary for the following
reason. When an object is added to a container, an object-added event
must be published.  Similarly, an add-notification hook is called on
the item if the item is add notifyable.  When an object is removed
from a container, an object-removed event must be published, and, if
the item being removed is delete notifiable, a deletion hook must be
called.  When an object is moved from one place to another, a single
object-moved event must be generated.  Moved events extend add and
removal events, so a single event is generated that is *both* an add
event and a deletion event.  There is no way to do this properly if
the events are generated by setObject and __delitem__.  These methods
can't distinguish between move, and add or removal.  Similarly, the
hooks called for moving (and copying, for that matter) are different
than the hooks called for simple addition and removal.  Furthermore,
objects may be moved between containers.  It makes no sense for one of
the containers to be responsible for generating the move events.

As described in the proposal, we'll provide adapters to automate
generating events and calling hooks and we'll make it easy to call
these adapters by providing functions in zapi::

   from zope.app import zapi

   zapi.add(container, name, object)

   zapi.remove(container, name)

I also proposed that responsibility for setting (and unsetting) __parent__
and __name__ attributes on contained objects be the responsibility of
the container.  I'm not so sure this makes sense any more.  It is
really incorrect to call setObject or __delitem__ directly any
more. If they are called directly, then necessary events won't be
published or hooks called.  We always need to go through zapi.add and
zapi.remove.  For this reason, I think it makes more sense to make
setting __parent__ and __name__ the responsibility of the adapters
(invoked by zapi.add and zapi.remove).

Finally, in another proposal:

   http://dev.zope.org/Zope3/ReplaceSetObjectWithSetitem

I proposed changing setObject so that it always uses the name passed
(unless it rejects it by raising an exception).  I'm implementing this
change as part of the parentgeddon work.

I also proposed that setObject should be renamed __setitem__.  This
has two advantages:

- It's simpler for implementors.  In fact, one could pretty much use
   a persistent dictionary, or even a BTree, as a container.

- It's simpler for clients, as they can use a familiar syntax.

Given the fact that containers must always be manipulated through
adapters, clients can't use the __setitem__ and __delitem__ operations
directly, so the second benefit goes away. In fact, the presense
of __setitem__ and __delitem__ might tempt clients to use them,
making them a liability.

Thoughts?

Jim


-- 
Jim Fulton           mailto:jim at zope.com       Python Powered!
CTO                  (703) 361-1714            http://www.python.org
Zope Corporation     http://www.zope.com       http://www.zope.org





More information about the Zope3-dev mailing list