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

2006-05-01 Thread Chris Withers

Florent Guillaume wrote:

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


OK, this is the code I went with.

Well the C code is pretty clear, it does a PyDict_Clear before doing 
PyDict_Update on the __dict__. Dunno how it was at the time Evan made 
his comment.


Well, there's tests now, so we should find out if this changes in the 
future...


OFS.tests.testCopySupport was a good starting place, but it used 
DemoStorage which doesn't support history, so I had to swap in a real, 
live filestorage ;-)


cheers,

Chris

--
Simplistix - Content Management, Zope  Python Consulting
   - http://www.simplistix.co.uk
___
For more information about ZODB, see the ZODB Wiki:
http://www.zope.org/Wikis/ZODB/

ZODB-Dev mailing list  -  ZODB-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zodb-dev


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

2006-04-29 Thread Florent Guillaume

Chris Withers wrote:

Florent Guillaume wrote:

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.


Right, that's what I figured too, and I'm guessing ZODB now does the 
right thing, which breaks history copy because history copy has this 
bug ;-)



  base._p_activate()   # make sure we're not a ghost


Ah cool, never new that existed...


  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.


Okay, in that case we can loose everything funky before the __setstate__ 
call, right? How sure are you that __setstate__ will override 
everything? I see that Evan specifically added the code to do the 
scrubbing in revision 20478, sadly he didn't write tests or explain why 
it was necessary :-S


Well the C code is pretty clear, it does a PyDict_Clear before doing 
PyDict_Update on the __dict__. Dunno how it was at the time Evan made 
his comment.


For the rest, sorry, I don't have time to dig for examples.

Florent


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


Hmmm, this smells like deep fu of which I am not capable ;-)
Are there any examples of this?

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

tests do that.


Oh, do you know of any examples I can look at?

cheers,

Chris




--
Florent Guillaume, Nuxeo (Paris, France)   Director of RD
+33 1 40 33 71 59   http://nuxeo.com   [EMAIL PROTECTED]
___
For more information about ZODB, see the ZODB Wiki:
http://www.zope.org/Wikis/ZODB/

ZODB-Dev mailing list  -  ZODB-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zodb-dev


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

2006-04-28 Thread Chris Withers

Florent Guillaume wrote:

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.


Right, that's what I figured too, and I'm guessing ZODB now does the 
right thing, which breaks history copy because history copy has this 
bug ;-)



  base._p_activate()   # make sure we're not a ghost


Ah cool, never new that existed...


  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.


Okay, in that case we can loose everything funky before the __setstate__ 
call, right? How sure are you that __setstate__ will override 
everything? I see that Evan specifically added the code to do the 
scrubbing in revision 20478, sadly he didn't write tests or explain why 
it was necessary :-S



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


Hmmm, this smells like deep fu of which I am not capable ;-)
Are there any examples of this?


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


Oh, do you know of any examples I can look at?

cheers,

Chris

--
Simplistix - Content Management, Zope  Python Consulting
   - http://www.simplistix.co.uk
___
For more information about ZODB, see the ZODB Wiki:
http://www.zope.org/Wikis/ZODB/

ZODB-Dev mailing list  -  ZODB-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zodb-dev


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

2006-04-27 Thread Florent Guillaume

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 RD
+33 1 40 33 71 59   http://nuxeo.com   [EMAIL PROTECTED]

___
For more information about ZODB, see the ZODB Wiki:
http://www.zope.org/Wikis/ZODB/

ZODB-Dev mailing list  -  ZODB-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zodb-dev