[ZODB-Dev] Re: Changes in _p_changed behaviour between Zope 2.7 and 2.9

Florent Guillaume fg at nuxeo.com
Thu Apr 27 12:36:47 EDT 2006


Chris Withers wrote:
> Hi All,
> 
> I'm trying to fix this bug:
> http://www.zope.org/Collectors/Zope/2062
> 
> And I've narrowed it down to the following lines in History.py:
> 
>         if serial != self._p_serial:
>             self.manage_beforeHistoryCopy()
>             state=self._p_jar.oldstate(self, serial)
>             print '1:',state
>             # Scrub the object before restoring the old state
>             base = aq_base(self)
>             base._p_changed=0

Marks the object not changed, to allow ghostifying.

>             base._p_deactivate()

Ghostifies the object.

>             base.__setstate__(state)

Updates the object's dict directly. This really shouldn't be called on a
ghost object, I believe it's illegal but not checked. I'm not sure what
happens anyway.

>             base._p_changed=1
> 
>             self.manage_afterHistoryCopy()
> 
> If I comment out the base._p_changed=0 and base._p_deactivate() then 
> history copy starts working again.
> 
> My theory now is that the _p_deactivate() causes the persistence 
> mechanisms to miss the changes made by base.__setstate__(state) and so 
> when base._p_changed=1, it takes what it thinks is a ghost and stomps 
> over it with the old state.
> 
> Does this sound plausible? If so, what's the correct fix here? Why was 
> the scrubbing process necessary?

The way I'd do it is:

   base._p_activate()       # make sure we're not a ghost
   base.__setstate__(state) # change the state
   base._p_changed = True   # marke object as dirty

The "scrubbing" is not necessary, it's done by the __setstate__ C
implementation of Persistent.

> Also, just as importantly, how would someone suggest writing a test that 
> excercises the above? The only thing I can thing of is creating a 
> scratch filestorage somewhere and committing some transactions to it, 
> but that seems a little heavyweight...

You don't need any transactions to at least test this sequence, only the
Persistent base class and a dummy connection can be involved.

To really test the history yes of course you'll need a full database. Many
tests do that.

Florent

-- 
Florent Guillaume, Nuxeo (Paris, France)   Director of R&D
+33 1 40 33 71 59   http://nuxeo.com   fg at nuxeo.com



More information about the ZODB-Dev mailing list