-
Notifications
You must be signed in to change notification settings - Fork 15
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
PersistentAdapterRegistry not compatible with pickle protocol 2 #34
Comments
The original issue is mostly my fault, sorry, I'm the one that switched the default pickle protocol. I'll try to take a look at this soon-ish, unless someone beats me to it. |
Nah, thanks for the change. I tried to get Jim to change the default protocol 7 years ago, but didn't convince him at the time (https://github.com/zopefoundation/ZODB/tree/hannosch-pickle-protocol2) ;-) It should be rare for any classes in the Zope world to implement their own get/setstate, so this issue shouldn't be widespread. |
I'm struggling to reproduce this from a fresh state. An empty
I can't find any code in either zope.interface or zope.component that can cope with attributes like Is there a subclass somewhere in Zope or its dependencies that handles a backwards-incompatible pickle? |
Hmm. I cannot reproduce this locally either. There's usually another subclass involved in the Zope 2/4 context from five.localsitemanager. But that doesn't seem to change the behavior either (https://github.com/zopefoundation/five.localsitemanager/blob/master/src/five/localsitemanager/registry.py#L210). I think we need to wait until we hear from @pbauer and what he can find. Maybe I misdiagnosed the problem completely and something else is at fault. |
Reverting to ZODB 5.2.4 had no effect. I guess it is not related to the pickle protocol since Plone 5.1rc1 already uses ZODB 5.3.0 without issues. Below is the complete output from startup to the traceback. It happens when creating a new Plone Site instance via the view @@plone-addsite. There are many more exciting errors in http://jenkins.plone.org/view/PLIPs/job/plip-zope4/42/consoleText if you are interested 😉
|
I'm not a Plone or Zope[2] guy, so I don't really know what all would be going on in that view, or the lifecycle of that request. If you feel like doing some debugging, some questions I had were:
|
Found it! It is a issue with trying to publish this error-message (grabbed from
The actions-portlet is somehow broken but that an a different issue... My first guess is that the change in exception-view-handling (zopefoundation/Zope#102) is to blame. There ,ay also be stuff from zopefoundation/Zope#174 missing (discussed in plone/Products.CMFPlone#1351 (comment)). |
Ok. I've managed to reproduce this locally. There is no issue with zope.component here. It looks like it's an issue with plone.testing and its layer setup. One of the earlier layers fails with the above mentioned To make things more interesting, the If I get rid of the broken registry via I think this issue can be closed here, unless someone thinks moving the invariant setup ( |
I think it's probably fine where it is. Pickle protocols less than 2 won't call >>> import cPickle
>>> class Foo(object):
... def __new__(cls):
... print("I'm new!")
... return object.__new__(cls)
... def __getstate__(self):
... return (1,)
... def __setstate__(self, state):
... print("Got state", state)
...
>>> foo = Foo()
I'm new!
>>> cPickle.loads(cPickle.dumps(foo, 1)) # Notice no __new__ called.
Got state (1,)
<__main__.Foo object at 0x10666a810>
>>> cPickle.loads(cPickle.dumps(foo, 2)) # This time it is.
I'm new!
Got state (1,)
<__main__.Foo object at 0x10666a8d0>
>>> def newargs(obj):
... print("Getting newargs")
... return ()
...
>>> Foo.__getnewargs__ = newargs
>>> cPickle.dumps(foo, 1) # Notice no __getnewargs__ called
'ccopy_reg\n_reconstructor\...'
>>> cPickle.loads(cPickle.dumps(foo, 2)) # They're both called
Getting newargs
I'm new!
Got state (1,)
<__main__.Foo object at 0x10666a8d0> |
For the curious: The reason for the orginal error was that portal tools are now utilities in recent CMFCore versions. Plone did not yet register these utilities, they could not be found and no action-categories were added on site-creation and so on... |
This was first discussed in unreleated comments in zopefoundation/Zope#188. Putting it here where it belongs:
There's this nice warning message on the pickle protocol page (https://docs.python.org/2/library/pickle.html):
The code in https://github.com/zopefoundation/zope.component/blob/master/src/zope/component/persistentregistry.py doesn't work with that for empty registries.
In the
__getstate__
it removes all its in-memory-only bits (everything in_delegated
), but that means it returns an empty value for an empty registry. When unpickling things,__init__
isn't called, so this code relies on theself._createLookup()
to be called as part of__setstate__
to put those in-memory objects back. Only this no longer happens thanks to the empty__getstate__
return value. I think that PersistentAdapterRegistry needs to implement a__new__
to populate its invariants, maybe a__getnewargs__
as well.The text was updated successfully, but these errors were encountered: