[Zope-dev] Proposal: set __parent__ and __name__ in Zope 2.12 OFS
Martin Aspeli
optilude+lists at gmail.com
Sun Apr 26 11:53:58 EDT 2009
Hi,
First - a quick question: can we treat __name__ and id/getId()/_setId()
as the same, always? OFS.SimpleItem has some support for letting id and
name be the same, but the link is lost once both __name__ and id are
set. Why isn't __name__ just a property that reflects self.id ?
Then, the proposal:
In Zope 2.12, acquisition wrappers are optional. Instead of using a
wrapper, acquisition can work by following __parent__ pointers. That
work well for views, where these are now set properly, but no content
currently maintains __parent__ pointers.
We can fix this by introducing some code in OFS (and BTreeFolder2) that
mimics what zope.container does. We can't use the setitem() and
uncontained() helpers directly, since these deal with containment
proxies and have slightly different semantics, but I think we can do this:
1) Add the following to _setOb:
def _setOb(self, id, object):
if ILocation.providedBy(object):
if not IContained.providedBy(object):
alsoProvides(object, IContained)
oldname = getattr(object, '__name__', None)
oldparent = getattr(object, '__parent__', None)
if id is not oldname:
object.__name__ = id
if self is not oldparent:
object.__parent__ = self
setattr(self, id, object)
2) Add the following to _delOb:
def _delOb(self, id):
""" Remove the named object from the folder. """
try:
obj = self._getOb(id, _marker)
if obj is not _marker:
if IContained.providedBy(obj):
obj.__parent__ = None
obj.__name__ = None
except AttributeError:
# No need to fail if we can't set these
pass
delattr(self, id)
Note that there's a slight discrepancy here with the way zope.container
works. In Zope 3, the __parent__ pointer is not unset until after the
ObjectRemovedEvent is fired. In Zope 2, we only fire that event after
the object has been fully removed (in _delObject()), but we have the
ObjectWillBeRemovedEvent that is fired before. I don't think this really
matters, though.
3) It'd be nice to also make ObjectManager and BTreeFolder2Base
support the IContainer interface, so that OFS containers can be used
with the more natural dict-like API of Zope 3 rather than the somewhat
obscure getattr()/_getOb()/_setObject()-vs-_setOb() and so on API we
have now.
To add this, we'd just need to add a few methods to ObjectManager that
calls the existing APIs, e.g. __getitem__, __delitem__, __setitem__ and
so on.
We have code for all three of these in plone.folder which could be
pushed down to OFS an BTreeFolder2 quite easily.
Martin
--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book
More information about the Zope-Dev
mailing list