1

グループにメンバーを追加するハンドラーがあります。このハンドラーの最後の行でエラーが発生します。

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()
4

1 に答える 1

2

pickleでこの種の問題が発生し、あなたのようにデバッグすることで解決しました。

Pickle (オブジェクトを ZODB に格納するために使用) が PloneUser をシリアル化しようとしており、このacquisition wrapperエラーが発生しています。

私の場合、portal_workflowオブジェクトを別の にラップしclassていたので、それを から継承しpickle.Pickler、メソッドをオーバーライド__getstate__して問題を解決する必要がありました。

このメソッドは、オブジェクトをシリアル化するために pickle によって呼び出されます。このメソッドをオーバーライドし、 thisobject.__dict__なしで返すとPloneUser、このエラーは発生しません。

この質問(あなたの正確な問題ではありませんが)には、私が言おうとしていることに関する詳細情報があります。

問題を解決できてよかったです。

于 2012-02-29T20:08:17.163 に答える