如何调试“TypeError:无法在采集包装器中挑选对象”。在Plone

时间:2011-11-29 13:37:30

标签: plone zope zodb

我有一个处理程序,可以将一个成员添加到一个组中。此处理程序中的最后一行导致错误:

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 'newuser@usecm.com'>, ('Default_Group',), 'maarten@usecm.com', ('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()

1 个答案:

答案 0 :(得分:2)

我遇到了泡菜这样的问题,并通过调试解决了问题。

Pickle(用于在ZODB中存储对象)正在尝试序列化您的PloneUser,并引发此acquisition wrapper错误。

在我的情况下,我将portal_workflow对象包装到另一个class中,并且必须从pickle.Pickler继承它,并覆盖__getstate__方法来解决我的问题。

pickle调用此方法以序列化您的对象。如果您覆盖此方法,并在没有此object.__dict__的情况下返回PloneUser,则不会引发此错误。

question(虽然没有您的确切问题)有更多关于我想说的内容的信息。

很高兴你可以解决你的问题。