Skip to content

render_kw for options are not passed on correctly to _Option in SelectFieldBase.__iter__ #882

@Daverball

Description

@Daverball

opt = self._Option(
label=label, id="%s-%d" % (self.id, i), **opts, **render_kw
)

Instead of merging render_kw with opts['render_kw'] they're directly used as arguments for the creation of the _Option instance. This code path currently doesn't appear to be exercised in the unit tests. You can easily reproduce this bug by adding a unit test to https://github.com/pallets-eco/wtforms/blob/main/tests/fields/test_radio.py that tries to pass in three-tuple choices instead of two-tuple choices.

Here's the SelectField test case adapted for RadioField:

def test_option_render_kw():
    F = make_form(
        a=RadioField(choices=[("a", "Foo", {"title": "foobar", "data-foo": "bar"})])
    )
    form = F(a="a")
    assert form.a() == (
        '<ul id="a">'
        '<li><input checked id="a-0" name="a" type="radio" '
        'value="a" title="foobar" data-foo="bar"> '
        '<label for="a-0">yes</label></li></ul>'
    )

The fix should be fairly simple, something like the following should work perfectly fine:

    def __iter__(self):
        opts = dict(
            widget=self.option_widget,
            validators=self.validators,
            name=self.name,
            _form=None,
            _meta=self.meta,
        )
        for i, choice in enumerate(self.iter_choices()):
            if len(choice) == 4:
                value, label, checked, render_kw = choice
                if render_kw and self.render_kw:
                    render_kw = self.render_kw | render_kw
                elif self.render_kw:
                    render_kw = self.render_kw
            else:
                value, label, checked = choice
                render_kw = self.render_kw

            opt = self._Option(
                label=label, id="%s-%d" % (self.id, i), render_kw=render_kw, **opts, 
            )
            opt.process(None, value)
            opt.checked = checked
            yield opt

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