Skip to content

Pickling Error with RelationList inside DictRow in AddForms #102

Description

@adrianschulz

After the update to Plone 5.2 with Python3, we noticed a pickling error in the AddForms of some contenttypes. After further investigation, we noticed that all affected contenttypes have a behavior with a contacts-field which is a DataGridField with a RelationList (see the following code).

class IContactRoleSpecification(Interface):

    role = schema.Choice(vocabulary=RoleVocabulary,
                         title=_(u'label_Role', default=u'Role'),
                         required=True)

    widget('contact',
           CustomRelatedItemsWidget,
           location_folders={'de': '/Plone/de/personen',
                             'en': '/Plone/en/people'},
           additional_favorites=[{'title': _(u'Current Context'),
                                  'de': '{Context}',
                                  'en': '{Context}'},
                                 {'title': _(u'Start Page'),
                                  'de': '{Start}',
                                  'en': '{Start}'},
                                 {'title': _(u'Contacts-Folder'),
                                  'de': '/Plone/de/personen',
                                  'en': '/Plone/en/people'}],
           selectableTypes=['Kontaktperson'],
           overrideRootPath=True,
           )
    contact = RelationList(title=_(u'label_Contacts', default=u'Contacts'),
                           value_type=RelationChoice(title=u'Contact',
                                                     source=CatalogSource()),
                           required=False,
                           missing_value=[],
                           default=[])


@provider(IFormFieldProvider)
class IDynamicContacts(model.Schema):

    directives.widget(contacts='collective.z3cform.datagridfield.DataGridFieldFactory')
    contacts = schema.List(
        value_type=DictRow(title=_(u'Contact with Role'),
                           schema=IContactRoleSpecification),
        title=_(u'label_contact_with_role', default=u'Contact with Role'),
        description=_(u'help_contact_with_role', default=u''),
        required=False)

If we save the object with an empty contacts-field we don’t get the pickling error. If we fill in a value the following error gets thrown.

Traceback (innermost last):
  Module ZPublisher.WSGIPublisher, line 156, in transaction_pubevents
  Module ZPublisher.WSGIPublisher, line 338, in publish_module
  Module ZPublisher.WSGIPublisher, line 256, in publish
  Module ZPublisher.mapply, line 85, in mapply
  Module ZPublisher.WSGIPublisher, line 62, in call_object
  Module plone.z3cform.layout, line 63, in __call__
  Module plone.z3cform.layout, line 47, in update
  Module plone.dexterity.browser.add, line 141, in update
  Module plone.z3cform.fieldsets.extensible, line 65, in update
  Module plone.z3cform.patch, line 30, in GroupForm_update
  Module z3c.form.group, line 145, in update
  Module plone.app.z3cform.csrf, line 22, in execute
  Module z3c.form.action, line 98, in execute
  Module z3c.form.button, line 315, in __call__
  Module z3c.form.button, line 170, in __call__
  Module plone.dexterity.browser.add, line 116, in handleAdd
  Module z3c.form.form, line 265, in createAndAdd
  Module plone.dexterity.browser.add, line 91, in add
  Module plone.dexterity.utils, line 189, in addContentToContainer
  Module Products.BTreeFolder2.BTreeFolder2, line 464, in _setObject
  Module zope.event, line 32, in notify
  Module zope.component.event, line 27, in dispatch
  Module zope.component._api, line 124, in subscribers
  Module zope.interface.registry, line 442, in subscribers
  Module zope.interface.adapter, line 607, in subscribers
  Module zope.component.event, line 36, in objectEventNotify
  Module zope.component._api, line 124, in subscribers
  Module zope.interface.registry, line 442, in subscribers
  Module zope.interface.adapter, line 607, in subscribers
  Module plone.app.versioningbehavior.subscribers, line 109, in create_initial_version_after_adding
  Module Products.CMFEditions.CopyModifyMergeRepositoryTool, line 336, in save
  Module Products.CMFEditions.CopyModifyMergeRepositoryTool, line 500, in _recursiveSave
  Module Products.CMFEditions.ArchivistTool, line 270, in prepare
  Module Products.CMFEditions.ArchivistTool, line 224, in _cloneByPickle
TypeError: Can't pickle objects in acquisition wrappers.

Again we investigated further and found the referenced object in the contacts-field is not a RelationValue and also wrapped in Acquisition-Wrappers (as the error-message shows).

Shouldn’t the value be stored as RelationValue? If not: Why?
Does anybody know why we encounter the problem only when adding an object and not when editing it?

As a workaround, we are now hiding the field in all the AddForms.

Relevant versions:

collective.z3cform.datagridfield = 1.5.2
plone.app.relationfield = 2.0.1
z3c.relationfield = 0.9.0
zc.relation = 1.1.post2
z3c.form = 3.7.0
plone.app.z3cform = 3.1.3
plone.autoform = 1.8.1

NOTE: For the described field we have a custom Serializer, Deserializer, and RelatedItemsWidget. But our tests without these custom elements showed the same error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions