Le 31/12/10 04:08, Marius Gedminas a écrit :
> On Fri, Dec 31, 2010 at 02:02:36AM +0100, Godefroid Chapelle wrote:
>> I have been fighting all day to understand a bug with the unregistration
>> of a utility from a local site.
>> After unregistration, some instance is left in the _subscribers list of
>> the utilities AdapterRegistry in my local site.
> Sounds like https://bugs.launchpad.net/zope.component/+bug/551049
>> This avoids me to remove the code as it does leave a broken object.
>> I have come to the conclusion that the code that first registered the
>> utility is the culprit : the utility itself is not persistent.
>> It seems that the utility instance is unserialized at least two times
>> during unregistration, which leads (if I understand well) to two
>> different objects in memory.
>> This breaks the unsubscription algorithm that is based on object identity.
> Actually, half of it is based on identity, and half on equality; when
> these disagree, you end up with inconsistent state.
> Your example is a good argument for making both halves use equality
> rather than identity.
>> I naively tried to introduce the Persistent base class into the utility
>> calss. When I try to access the utility instance again, I get the error
>> mentioned in the subject of this mail :
>> TypeError: ('object.__new__(SyncedLanguages) is not safe, use
>> Persistence.Persistent.__new__()',<function _reconstructor at
>> 0x1004297d0>, (<class
>> 'Products.LinguaPlone.vocabulary.SyncedLanguages'>,<type 'object'>, None))
>> If I understand well, the a posteriori introduction of Persistent cannot
>> happen alone.
>> Can anyone tell me what I should do add to the class I try to make it
>> actually persistent ?
> I think a more fruitful approach would be to fix the zope.component bug
> and then unregister the utility in the normal way.
Marius, did you already try to fix zope.component ? Is it because it is
hard that you accepted the Won't fix ? Or because of lack of time ?
> Alternatively, you could hack up a __new__ method to always return the
> same instance, so you can unregister it cleanly before removing the
> code. This will not work if you have more than one instance in the DB.
Could that __new__ method insert Persistent as a base class if not present ?
> Fixing up _subscribers directly is also a possible workaround, if you're
> feeling brave.
> Marius Gedminas
Thanks for your help.
Godefroid Chapelle (aka __gotcha) http://bubblenet.be
For more information about ZODB, see the ZODB Wiki:
ZODB-Dev mailing list - ZODB-Dev@zope.org