Zope 2.12 PythonScript manage_change_history_page functionalities broken for old objects

Bug #735999 reported by Vincent Pelletier
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Zope 2
Invalid
Low
Unassigned

Bug Description

How to reproduce:
- Create an instance with an old Zope version (in my case: 2.8.8)
- Create a PythonScript object, maybe edit a few times (just to have more than one revisions, to show the problem is not an edge case of a new object)
- Upgrade to newer Zope (in my case: 2.12)
- Go to the same PythonScript, maybe edit again a few times (same goal as above)
- Go to History page
- Try to diff script with an old revision of itself, or to display old revisions
What happens:
When one of the loaded revision was created before the upgrade, it fails with an AssertionError in ZOPE/Connection.py:register on "assert obj._p_jar is self".
Indeed:
(Pdb) obj._p_jar.__class__
<class OFS.History.HystoryJar at 0xb65dabcc>
(Pdb) self.__class__
<class 'ZODB.Connection.Connection'>

This happens, as far as I understand, because of this:
> Zope2-2.12.15-py2.6-linux-i686.egg/Products/PythonScripts/PythonScript.py(224)__setstate__()
((Pdb)) getattr(self, 'Python_magic', None)
'm\xf2\r\n'
((Pdb)) Python_magic
'\xd1\xf2\r\n'

Which leads to...
229 if body:
230 self._body = body + '\n'

And assigning to self._body in turn causes object to be registered to ZODB.Connection, in turn causing the assertion error.

Changed in zope2:
importance: Undecided → Low
status: New → Confirmed
Revision history for this message
Vincent Pelletier (vincent-nexedi) wrote :

Attached patch fixes the problem for me.

I applied the same order here as what happens when calling ZODB.Connection.load: first __setstate__, then put _p_serial, and finally prevent any change by setting a different jar.

Notes (unrelated to this fix, but related to modified code):
- This function breaks if object class changed between observed and current revision
  Reason: rev=self.__class__.__basicnew__()
  Possible solution: ZODB should probably offer a way to load an old instance into a usable object, rather than exposing a bare state.
- HystoryJar is not strictly required to raise in commit actually. It's anyway probably better to keep it here, in case ZODB stops checking jar (...not that I think it will really happen).

Revision history for this message
Colin Watson (cjwatson) wrote :

The zope2 project on Launchpad has been archived at the request of the Zope developers (see https://answers.launchpad.net/launchpad/+question/683589 and https://answers.launchpad.net/launchpad/+question/685285). If this bug is still relevant, please refile it at https://github.com/zopefoundation/zope2.

Changed in zope2:
status: Confirmed → Invalid
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.