zopefoundation / z3c.form

An advanced form and widget framework for Zope 3
Other
9 stars 39 forks source link

Duplicate name: value #99

Open NicolasGoeddel opened 3 years ago

NicolasGoeddel commented 3 years ago

BUG/PROBLEM REPORT (OR OTHER COMMON ISSUE)

What I did:

I created a new control panel, derived from plone.supermodel.model.Schema and then used together with a plone.app.registry.browser.controlpanel.RegistryEditForm and the plone.app.registry.browser.controlpanel.ControlPanelWrapper.

class IControlPanel(model.Schema):

    site_color = field.TextLine(
        title=_('page_color', default='Farbe der Seite'),
        description=_('page_color_desc', default='Geben Sie die Farbe der Seite an.'),
        required=False
    )

    site_email = field.TextLine(
        title='E-Mail der Website',
        description='E-Mails der Website werden an diese E-Mail gesendet.',
        required=False
    )

What happened:

After a reinstall of my addon I always get this error: https://github.com/zopefoundation/z3c.form/blob/68b3f8008881a5b44dcf9ecfc675da4a742256a3/src/z3c/form/field.py#L134 Or to be exact:

Traceback (innermost last):
  Module ZPublisher.WSGIPublisher, line 162, in transaction_pubevents
  Module ZPublisher.WSGIPublisher, line 359, in publish_module
  Module ZPublisher.WSGIPublisher, line 254, in publish
  Module ZPublisher.mapply, line 85, in mapply
  Module ZPublisher.WSGIPublisher, line 63, in call_object
  Module plone.z3cform.layout, line 63, in __call__
  Module plone.z3cform.layout, line 47, in update
  Module plone.z3cform.fieldsets.extensible, line 64, in update
  Module plone.autoform.form, line 34, in updateFields
  Module plone.autoform.base, line 68, in updateFieldsFromSchemata
  Module plone.autoform.utils, line 279, in processFields
  Module z3c.form.field, line 137, in __init__
ValueError: ('Duplicate name', 'value')

It reminds a lot of this one: https://github.com/plone/plone.behavior/issues/14

What I think

In line 130 of the same file the field (plone.registry.field.TextLine) of my schema gets wrapped inside a newly created Field instance. Then in the next line the name will be derived from it. But this name always seems to be "value" instead of the real field name. If I run the debugger before the exception I can see this:

# field <=> site_email
# self._data['value'] <=> site_color
(Pdb) field.title
'E-Mail der Website'
(Pdb) self._data
{'value': <Field 'value'>}
(Pdb) self._data['value']
<Field 'value'>
(Pdb) self._data['value'].field
<plone.registry.field.TextLine object at 0x7f4725e8c0b0 oid 0x17b2f in <Connection at 7f4739e34dc0>>
(Pdb) self._data['value'].field.title
'page_color'
(Pdb) self._data['value'].field.__name__
'value'
(Pdb) self._data['value'].__name__
'value'
(Pdb) field.__name__
'value'

So it seems that the original field also has the name "value" which is weird. Of course it should be site_color and site_email.

Should name not remain untouched?

What version of Python and Zope/Addons I am using:

Python 3.8.2 Zope 4.5.1 Plone 5.2.2

d-maurer commented 3 years ago

NicolasGoeddel wrote at 2020-10-21 08:23 -0700:

... After a reinstall of my addon I always get this error: https://github.com/zopefoundation/z3c.form/blob/68b3f8008881a5b44dcf9ecfc675da4a742256a3/src/z3c/form/field.py#L134 Or to be exact:

Traceback (innermost last):
...
 Module plone.z3cform.layout, line 63, in __call__
 Module plone.z3cform.layout, line 47, in update
 Module plone.z3cform.fieldsets.extensible, line 64, in update
 Module plone.autoform.form, line 34, in updateFields
 Module plone.autoform.base, line 68, in updateFieldsFromSchemata
 Module plone.autoform.utils, line 279, in processFields
 Module z3c.form.field, line 137, in __init__
ValueError: ('Duplicate name', 'value')

It reminds a lot of this one: https://github.com/plone/plone.behavior/issues/14

I doubt very much that this is a z3c.form problem: the ValueError is raised by Fields (i.e. a "field manager") when it sees a second field with the same name. This must (understandably) not happen: all field names managed by the same "field manager" must be unique.

The problem is higher up where the fields are prepared for the Fields call.

What I think

In line 130 of the same file the field (plone.registry.field.TextLine) of my schema gets wrapped inside a newly created Field instance. Then in the next line the name will be derived from it. But this name always seems to be "value" instead of the real field name.

If you look at the definition of Field.__init__ (lines 72ff), you will see that the __name__ of the created field is essentially determined by the input parameters, especially name and field.__name__. The means that the wrapping does not invent value. Instead, value comes from up level.

NicolasGoeddel commented 3 years ago

I also fiddled a bit around and found out that the issue was that I used plone.registry.field.TextLine instead of zope.schema.TextLine. So maybe this is not an issue anymore but the exception was just not that helpful to me.

On the other hand I also have a field like this:

    resourceOrder = zope.schema.List(
        title=_("resource_order", default="Resource Order"),
        description=_("resource_order_desc", default="..."),
        required=False,
        value_type=plone.registry.field.Choice(
            vocabulary=registeredResourcesStatic
        )
    )

Here it seems essential to use plone.registry.field.Choice as value_type because else the form can not be rendered. However I found that out by try and error because the documentation is not that great.

I guess this issue can be closed then.