Chris Withers wrote:
I'm trying to fix this bug:
And I've narrowed it down to the following lines in History.py:
if serial != self._p_serial:
# Scrub the object before restoring the old state
base = aq_base(self)
Marks the object not changed, to allow ghostifying.
Ghostifies the object.
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
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 Guillaume, Nuxeo (Paris, France) Director of R&D
+33 1 40 33 71 59 http://nuxeo.com [EMAIL PROTECTED]
For more information about ZODB, see the ZODB Wiki:
ZODB-Dev mailing list - ZODB-Dev@zope.org