Bug with recursing into opaque items (__recurse in
CMFCatalogAware) was: [Zope-CMF] Bug with CMFUid content when copied
indirectly and some confusion.
Gregoire Weber
gregweb at gmx.ch
Wed Aug 25 10:45:29 EDT 2004
Hi Tres,
I have a fix for the bug Tim found. '__recurse' in CMFCatalogAware has to be fixed.
As this is a central part of the code beeing called on all add/clone/move and
delete actions I'd like to put the solution under discussion.
Index: CMFCatalogAware.py
===================================================================
RCS file: /cvs-repository/Products/CMFCore/CMFCatalogAware.py,v
retrieving revision 1.21
diff -r1.21 CMFCatalogAware.py
194,200c194,213
< for subobjects in values, opaque_values:
< for ob in subobjects:
< s = getattr(ob, '_p_changed', 0)
< if hasattr(aq_base(ob), name):
< getattr(ob, name)(*args)
< if s is None: ob._p_deactivate()
<
---
>
> for ob in values:
> s = getattr(ob, '_p_changed', 0)
> if hasattr(aq_base(ob), name):
> getattr(ob, name)(*args)
> if s is None: ob._p_deactivate()
>
> # opaque items are subitems of self and not ofsubitems
> # self's parent. So before recursing the arguments have to be set:
> # arg[0] to self (the opaque item)
> # arg[1] to item (the item the opaque item is attachted at)
> # the container of the item isn't relevant for recursing into
> # opaque items
> args = [self, args[0]][:len(args)]
> for ob in opaque_values:
> s = getattr(ob, '_p_changed', 0)
> if hasattr(aq_base(ob), name):
> getattr(ob, name)(*args)
> if s is None: ob._p_deactivate()
>
I'm pretty sure the old soultion is a bug that never appeared because
the wrong parameters passed were never really used by the 'talkback'
object.
If there are no objections, I'll check this in friday morning.
Unit tests pass (except those who were broken anyway under Win2k).
Gregoire
At 11:10 25.08.2004 +0200, Gregoire Weber wrote:
>Thanks Tim!
>
>There is definitely a bug. There is a short term fix for CMFUid but it
>seems the real cause (and bug) lives in CMFCatalogAware. There seems to
>be a problem with the handling of opaque items (non SimpleItems).
>
>I'm currently investigating on that.
>
>Tres: A e-mail about the behaviour of __recurse calling opaque items
> will follow today.
>
>Gregoire
>
>My answers to your questions:
>
>At 14:33 25.08.2004 +0800, Tim Hoffman wrote:
>>I am exploring/testing the CMFUid functionality of the new CMF 1.5.0 Beta,
>>(I have been using my own Uid tool for some time, but it
>>relied on the use of a monkey patch which added a mixin class to
>>all PortalContent and PortalFolder plus a few others to ensure that all
>>CMFContent automgically got unique ids and managment and control of the
>>uid generation (especially after copying ;-) could be enforced.
>>
>>This approach is a support nightmare however, so I have always been
>>looking for a more supportable mechanism hence the investigation of
>>CMFUid.)
>
>CMFUid enforces that in marking the annotation object as 'ICallableOpaqueItem'
>(see 'IUniqueIdAnnotation' in interfaces.py). This way it gets called on
>copying and can destroy itself.
>
>>Anyway I am trying to fathom exactly how CMFUid works and have a couple
>>of questions. (plus I have noticed what I believe to be a bug)
>>
>>As I understand it, a call to uidtool.register(object) is in main
>>template. This gets called and if the object doesn't have a uid a new uid
>>(UniqueIdAnnotion instance) is created and stored as an attribute
>>if the content object (currently named cmf_uid). (UniqueIdAnnotation has
>>manage_afterAdd and manage_afterClone methods etc). So far so good.
>
>Ok.
>
>>However I don't understand how the manage_afterAdd/Clone methods get
>>called.
>>
>>A normal content object has manage_afterClone/Add by virtue of
>>ultimately subclassing things like ObjectManager/CatalogAware (CopySupport
>>Mixin) etc.
>>
>>But all of these methods iterate over result of objectValues() calling
>>manage_afterClone,manage_afterAdd on each as appropriate.
>>
>>But becuase the UniqueIdAnnotation is stored as an attribute calling
>>contentValues on a content object that has a uid doesn't return
>>the UniqueIdAnnotation object (it isn't based on
>>SimpleContent/ObjectManager but Persistent and Implicit).
>>
>>SO I am a bit confused how when one copies a content object how the
>>uid is being updated. As I can't find anything that might call
>>object.cmf_uid.manage_afterClone/Add and cmf_uid will never be
>>returned from a call to objectValues(). Am I missing something here?
>
>'cmf_uid' get's called by the 'opaqueItems' method in CMFCatalogAware.py
>in CMFCore because it is marked withe the 'ICallableOpaqueItem' interface.
>
>This is new in CMF 1.5 also (I integrated that in to CMFCore this january).
>
>>Now I come to the bug I think I have encountered.
>>If you copy a folder with content, the contained contents UID's
>>do not get updated ending up with duplicate UID's. Which I believe is a
>>bug. If you copy the content directly the uid does get updated.
>
>Uuups! See above.
>
>_______________________________________________
>Zope-CMF maillist - Zope-CMF at lists.zope.org
>http://mail.zope.org/mailman/listinfo/zope-cmf
>
>See http://collector.zope.org/CMF for bug reports and feature requests
More information about the Zope-CMF
mailing list