[Zope-dev] Proposal: set __parent__ and __name__ in Zope 2.12 OFS

Laurence Rowe l at lrowe.co.uk
Mon Apr 27 13:02:26 EDT 2009


Martin Aspeli wrote:
> 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 ?

I would prefer this to be the other way around -- getId() /  _setId() 
should operate on __name__. It will be easier to drop OFS support in the 
future if pickles store the real __name__ and __parent__ attributes. We 
will presumably require a migration now anyway to add __parent__ pointers.

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

+1

Laurence



More information about the Zope-Dev mailing list