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. """
             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

         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.


Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book

Zope-Dev maillist  -  Zope-Dev@zope.org
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://mail.zope.org/mailman/listinfo/zope )

Reply via email to