New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate Plone site from Zope2 2.13 to Zope2 4.0b3.dev0 #205

Closed
bsuttor opened this Issue Oct 21, 2017 · 5 comments

Comments

Projects
None yet
2 participants
@bsuttor
Member

bsuttor commented Oct 21, 2017

python version : 2.7.14

Steps to reproduce :

  • create Plone site on Zope2 2.13 (Plone 5.1) (with buildout.coredev)
  • restart buildout with "-c plip-zope4.cfg" option (use Zope2 4.0b3)
  • start instance
2017-10-21 11:34:22 ERROR ZODB.Connection Couldn't load state for OFS.Application.Application 0x01 
Traceback (most recent call last): 
  File "/home/bsuttor/.buildout/eggs/ZODB-5.3.0-py2.7.egg/ZODB/Connection.py", line 800, in setstate
    self._reader.setGhostState(obj, p) 
  File "/home/bsuttor/.buildout/eggs/ZODB-5.3.0-py2.7.egg/ZODB/serialize.py", line 622, in setGhostState
    state = self.getState(pickle)
  File "/home/bsuttor/.buildout/eggs/ZODB-5.3.0-py2.7.egg/ZODB/serialize.py", line 615, in getState
    return unpickler.load()         
TypeError: ('__init__() takes exactly 2 arguments (1 given)', <class 'ZPublisher.BeforeTraverse.NameCaller'>, ())  

@pbauer pbauer referenced this issue Oct 22, 2017

Open

PLIP: Update Zope Dependencies #1351

4 of 5 tasks complete
@icemac

This comment has been minimized.

Show comment
Hide comment
@icemac

icemac Oct 23, 2017

Contributor

Expect the same error you got for ZPublisher.BeforeTraverse.NameCaller for the following classes, too:

  • ZPublisher.BeforeTraverse.MultiHook
  • Shared.DC.Scripts.Signature.FuncCode
  • Shared.DC.Scripts.Bindings.NameAssignments

Instances of these classes are stored in pickles in the ZODB. They have a constructor (__init__ method) which seems to be called during unpicking.

This behaviour is independent from the ZODB:

>>> class A:
...     def __init__(self, x):
...         self.x = x

>>> a = A(42)
>>> import pickle
>>> pickle.dumps(a)
"(i__main__\nA\np0\n(dp1\nS'x'\np2\nI42\nsb."

When trying to read this pickle in a different Python 2.7 interpreter you get:

>>> class A(object):
...     def __init__(self, x):
...         self.x = x
...
>>> import pickle
>>> pickle.loads("(i__main__\nA\np0\n(dp1\nS'x'\np2\nI42\nsb.")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/pickle.py", line 1388, in loads
    return Unpickler(file).load()
  File "/usr/lib/python2.7/pickle.py", line 864, in load
    dispatch[key](self)
  File "/usr/lib/python2.7/pickle.py", line 1076, in load_inst
    self._instantiate(klass, self.marker())
  File "/usr/lib/python2.7/pickle.py", line 1066, in _instantiate
    value = klass(*args)
TypeError: in constructor for A: __init__() takes exactly 2 arguments (1 given)

A solution could be to make the argument of __init__ optional:

>>> class A(object):
...     def __init__(self, x=None):
...         self.x = x
...
>>> import pickle
>>> a2 = pickle.loads("(i__main__\nA\np0\n(dp1\nS'x'\np2\nI42\nsb.")
>>> a2.x
42
>>> pickle.dumps(a2)
"ccopy_reg\n_reconstructor\np0\n(c__main__\nA\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\n(dp5\nS'x'\np6\nI42\nsb."
>>> pickle.loads(pickle.dumps(a2)).x
42

The pickle changes by switching from old-style classes to new-style classes, but it can be read again. So this seems to be okay.

Contributor

icemac commented Oct 23, 2017

Expect the same error you got for ZPublisher.BeforeTraverse.NameCaller for the following classes, too:

  • ZPublisher.BeforeTraverse.MultiHook
  • Shared.DC.Scripts.Signature.FuncCode
  • Shared.DC.Scripts.Bindings.NameAssignments

Instances of these classes are stored in pickles in the ZODB. They have a constructor (__init__ method) which seems to be called during unpicking.

This behaviour is independent from the ZODB:

>>> class A:
...     def __init__(self, x):
...         self.x = x

>>> a = A(42)
>>> import pickle
>>> pickle.dumps(a)
"(i__main__\nA\np0\n(dp1\nS'x'\np2\nI42\nsb."

When trying to read this pickle in a different Python 2.7 interpreter you get:

>>> class A(object):
...     def __init__(self, x):
...         self.x = x
...
>>> import pickle
>>> pickle.loads("(i__main__\nA\np0\n(dp1\nS'x'\np2\nI42\nsb.")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/pickle.py", line 1388, in loads
    return Unpickler(file).load()
  File "/usr/lib/python2.7/pickle.py", line 864, in load
    dispatch[key](self)
  File "/usr/lib/python2.7/pickle.py", line 1076, in load_inst
    self._instantiate(klass, self.marker())
  File "/usr/lib/python2.7/pickle.py", line 1066, in _instantiate
    value = klass(*args)
TypeError: in constructor for A: __init__() takes exactly 2 arguments (1 given)

A solution could be to make the argument of __init__ optional:

>>> class A(object):
...     def __init__(self, x=None):
...         self.x = x
...
>>> import pickle
>>> a2 = pickle.loads("(i__main__\nA\np0\n(dp1\nS'x'\np2\nI42\nsb.")
>>> a2.x
42
>>> pickle.dumps(a2)
"ccopy_reg\n_reconstructor\np0\n(c__main__\nA\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\n(dp5\nS'x'\np6\nI42\nsb."
>>> pickle.loads(pickle.dumps(a2)).x
42

The pickle changes by switching from old-style classes to new-style classes, but it can be read again. So this seems to be okay.

icemac added a commit that referenced this issue Oct 23, 2017

Fix unpickling of instances those base class changed to a new-style c…
…lass.

If the instance was created before Zope 4.0b2 unpickling broke because in 4.0b2 all classes became new-style classes.

Fixes #205.
@icemac

This comment has been minimized.

Show comment
Hide comment
@icemac

icemac Oct 23, 2017

Contributor

@bsuttor I sketched a possible solution in #208. Could you please try with the branch used there and report back if it helps?

Contributor

icemac commented Oct 23, 2017

@bsuttor I sketched a possible solution in #208. Could you please try with the branch used there and report back if it helps?

@icemac

This comment has been minimized.

Show comment
Hide comment
@icemac

icemac Oct 23, 2017

Contributor

Maybe there are other classes besides the ones mentioned in this ticket which have the same problem.

Contributor

icemac commented Oct 23, 2017

Maybe there are other classes besides the ones mentioned in this ticket which have the same problem.

@icemac icemac added this to the 4.0b3 milestone Oct 23, 2017

@icemac icemac closed this in #208 Oct 24, 2017

icemac added a commit that referenced this issue Oct 24, 2017

Fix unpickling of instances those base class changed to a new-style c…
…lass. (#208)

If the instance was created before Zope 4.0b2 unpickling broke because in 4.0b2 all classes became new-style classes.

Fixes #205.
@bsuttor

This comment has been minimized.

Show comment
Hide comment
@bsuttor

bsuttor Oct 24, 2017

Member

@icemac thank you,
I will try tomorrow or after tomorrow

Member

bsuttor commented Oct 24, 2017

@icemac thank you,
I will try tomorrow or after tomorrow

@bsuttor

This comment has been minimized.

Show comment
Hide comment
@bsuttor

bsuttor Oct 26, 2017

Member

I just try it, and it works,
Now Zope2 4.0b3 can start with a Plone site created on Zope2 2.13.

Thank you

Member

bsuttor commented Oct 26, 2017

I just try it, and it works,
Now Zope2 4.0b3 can start with a Plone site created on Zope2 2.13.

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment