如何调试“类型错误:无法在获取包装器中腌制对象。”在普隆
我有一个处理程序将成员添加到组中。该处理程序中的最后一行导致错误:
TypeError: Can't pickle objects in acquisition wrappers.
> /home/mnieber/.buildout/eggs/ZODB3-3.10.3-py2.6-linux-i686.egg/ZODB/serialize.py(431)_dump()
430 self._p.dump(classmeta)
--> 431 self._p.dump(state)
432 self._file.truncate()
在 pdb 调试器中,我可以看到 Plone 确实正在尝试腌制一个作为采集包装器的值:
ipdb> state
((((<PloneUser '[email protected]'>, ('Default_Group',), '[email protected]', ('PAS',)),),),)
ipdb> type(state[0][0][0][0])
<type 'Acquisition.ImplicitAcquisitionWrapper'>
但是,我看不到正在腌制哪个对象,因此我不知道哪个对象我的部分代码需要修复。我的问题是:我应该如何调试这个错误?我尝试查看所有堆栈帧,但没有一个显示正在序列化的对象。
处理程序就是这个(run_insecure 是一个装饰器,我用它来临时安装一个新的安全管理器,以避免在添加新成员时出现 NotAuthorized 错误):
@adapter(IPrincipalCreatedEvent)
@run_insecure
def userCreatedHandler(event):
portal_groups = getToolByName(getSite(), "portal_groups")
membersGroup = portal_groups.getGroupById('Default_Group')
membersGroup.addMember(event.principal)
完整的错误是这个:
Traceback (innermost last):
Module ZPublisher.Publish, line 134, in publish
Module Zope2.App.startup, line 301, in commit
Module transaction._manager, line 89, in commit
Module transaction._transaction, line 329, in commit
Module transaction._transaction, line 443, in _commitResources
Module ZODB.Connection, line 567, in commit
Module ZODB.Connection, line 623, in _commit
Module ZODB.Connection, line 658, in _store_objects
Module ZODB.serialize, line 422, in serialize
Module ZODB.serialize, line 431, in _dump
TypeError: Can't pickle objects in acquisition wrappers.
> /home/mnieber/.buildout/eggs/ZODB3-3.10.3-py2.6-linux-i686.egg/ZODB/serialize.py(431)_dump()
430 self._p.dump(classmeta)
--> 431 self._p.dump(state)
432 self._file.truncate()
I have a handler that adds a Member to a Group. The last line in this handler causes an error:
TypeError: Can't pickle objects in acquisition wrappers.
> /home/mnieber/.buildout/eggs/ZODB3-3.10.3-py2.6-linux-i686.egg/ZODB/serialize.py(431)_dump()
430 self._p.dump(classmeta)
--> 431 self._p.dump(state)
432 self._file.truncate()
In the pdb debugger I can see that indeed Plone is trying to pickle a value that is an Acquisition wrapper:
ipdb> state
((((<PloneUser '[email protected]'>, ('Default_Group',), '[email protected]', ('PAS',)),),),)
ipdb> type(state[0][0][0][0])
<type 'Acquisition.ImplicitAcquisitionWrapper'>
However, I cannot see which object is being pickled, and therefore I have no idea which part of my code needs fixing. My question is: how should I go about debugging this error? I have tried looking at all the stack frames, but none of them reveal which object is being serialized.
The handler is this one (run_insecure is a decorator that I use to temporarily install a new security manager that avoids a NotAuthorized error when adding the new member):
@adapter(IPrincipalCreatedEvent)
@run_insecure
def userCreatedHandler(event):
portal_groups = getToolByName(getSite(), "portal_groups")
membersGroup = portal_groups.getGroupById('Default_Group')
membersGroup.addMember(event.principal)
The full error is this one:
Traceback (innermost last):
Module ZPublisher.Publish, line 134, in publish
Module Zope2.App.startup, line 301, in commit
Module transaction._manager, line 89, in commit
Module transaction._transaction, line 329, in commit
Module transaction._transaction, line 443, in _commitResources
Module ZODB.Connection, line 567, in commit
Module ZODB.Connection, line 623, in _commit
Module ZODB.Connection, line 658, in _store_objects
Module ZODB.serialize, line 422, in serialize
Module ZODB.serialize, line 431, in _dump
TypeError: Can't pickle objects in acquisition wrappers.
> /home/mnieber/.buildout/eggs/ZODB3-3.10.3-py2.6-linux-i686.egg/ZODB/serialize.py(431)_dump()
430 self._p.dump(classmeta)
--> 431 self._p.dump(state)
432 self._file.truncate()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我在pickle中遇到了这种问题,并像你一样通过调试解决了。
Pickle(用于在 ZODB 中存储对象)正在尝试序列化您的 PloneUser,并引发此
获取包装
错误。就我而言,我将
portal_workflow
对象包装到另一个class
中,并且必须从pickle.Pickler
继承它,并覆盖__getstate__
方法来解决我的问题。pickle 调用此方法来序列化您的对象。如果您重写此方法,并返回没有此
PloneUser
的object.__dict__
,则不会引发此错误。这个问题(虽然不是你的确切问题)有更多关于我想说的信息。
很高兴你能解决你的问题。
I got this kind of problem with pickle, and solved by debugging like you did.
Pickle (used to store objects in ZODB) is trying to serialize your PloneUser, and raising this
acquisition wrapper
error.In my case, I was wrapping the
portal_workflow
object into anotherclass
, and had to inherit it frompickle.Pickler
, and override__getstate__
method to solve my problem.This method is called by pickle in order to serialize your object. If you override this method, and return your
object.__dict__
without thisPloneUser
, than this error would not be raised.This question (although with not your exact problem) have more info about what I'm trying to say.
Nice you could solve your problem.