pallets-eco/flask-wtf

WTForms 3.2.1 introduces incompatibility with flask-wtf

Closed this issue · 4 comments

Actual Behavior

WTForms 3.2.1 introduced incompatibility with flask-wtf

We see yet another failure with new WTForms - seems that field_flags is now a tuple but it was dictionry and uit causes an internal error when wtforms are used by flask appbuilder. Not sure how to easily reproduce it as it is deepl stack trace with werkzeug -> flask -> flask_wtf -> wtf. I am sorry it might not be minimal, but I see no easy way how to repro other than providing a stack trace from our tests in Apache Airflow

Example failure: https://github.com/apache/airflow/actions/runs/11441304988/job/31829670288#step:7:14662

tests/www/views/test_views_variable.py:219: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/local/lib/python3.9/site-packages/werkzeug/test.py:1146: in post
    return self.open(*args, **kw)
/usr/local/lib/python3.9/site-packages/flask/testing.py:238: in open
    response = super().open(
/usr/local/lib/python3.9/site-packages/werkzeug/test.py:1095: in open
    response = self.run_wsgi_app(request.environ, buffered=buffered)
/usr/local/lib/python3.9/site-packages/werkzeug/test.py:962: in run_wsgi_app
    rv = run_wsgi_app(self.application, environ, buffered=buffered)
/usr/local/lib/python3.9/site-packages/werkzeug/test.py:1243: in run_wsgi_app
    app_rv = app(environ, start_response)
/usr/local/lib/python3.9/site-packages/flask/app.py:2552: in __call__
    return self.wsgi_app(environ, start_response)
/usr/local/lib/python3.9/site-packages/flask/app.py:2532: in wsgi_app
    response = self.handle_exception(e)
/usr/local/lib/python3.9/site-packages/flask/app.py:2529: in wsgi_app
    response = self.full_dispatch_request()
/usr/local/lib/python3.9/site-packages/flask/app.py:1825: in full_dispatch_request
    rv = self.handle_user_exception(e)
/usr/local/lib/python3.9/site-packages/flask/app.py:1823: in full_dispatch_request
    rv = self.dispatch_request()
/usr/local/lib/python3.9/site-packages/flask/app.py:1799: in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
/usr/local/lib/python3.9/site-packages/flask_appbuilder/security/decorators.py:137: in wraps
    return f(self, *args, **kwargs)
/usr/local/lib/python3.9/site-packages/flask_appbuilder/views.py:586: in add
    widget = self._add()
/usr/local/lib/python3.9/site-packages/flask_appbuilder/baseviews.py:1216: in _add
    form = self.add_form.refresh()
/usr/local/lib/python3.9/site-packages/flask_appbuilder/forms.py:327: in refresh
    form = self(obj=obj)
/usr/local/lib/python3.9/site-packages/wtforms/form.py:209: in __call__
    return type.__call__(cls, *args, **kwargs)
/usr/local/lib/python3.9/site-packages/flask_wtf/form.py:73: in __init__
    super().__init__(formdata=formdata, **kwargs)
/usr/local/lib/python3.9/site-packages/wtforms/form.py:281: in __init__
    super().__init__(self._unbound_fields, meta=meta_obj, prefix=prefix)
/usr/local/lib/python3.9/site-packages/wtforms/form.py:49: in __init__
        self.check_validators(validators)
        self.validators = validators or self.validators
    
        self.id = id or self.name
        self.label = Label(
            self.id,
            label
            if label is not None
            else self.gettext(name.replace("_", " ").title()),
        )
    
        if widget is not None:
            self.widget = widget
    
        for v in itertools.chain(self.validators, [self.widget]):
            flags = getattr(v, "field_flags", {})
    
>           for k, v in flags.items():
E           AttributeError: 'tuple' object has no attribute 'items'


`/usr/local/lib/python3.9/site-packages/wtforms/fields/core.py:133: AttributeError

Expected Behavior

The tests should pass - like they did with 3.1.*

Environment

  • Python version: 3.9 - 3.12
  • wtforms version: 3.2.1

Thank you for your report.

After looking closer, it seems the issue is due to flask-appbuilder Unique validator using tuple flags.

https://github.com/dpgaspar/Flask-AppBuilder/blob/1d27eb42a4f9b6e19fb3c025327b4110b175eccb/flask_appbuilder/validators.py#L29

Tuple flags were deprecated in favor of dict flags, and raised warning since 2020, so with 3.2 we removed the deprecated code (#859). I suggest you report the issue to flask-appbuilder.

Tuple flags were deprecated in favor of dict flags, and raised warning since 2020, so with 3.2 we removed the deprecated code (#859). I suggest you report the issue to flask-appbuilder.

OK. Thanks for fast response. I will. Daniel is working on FAB 5.0 so I will flag it to him. In the meantime we limit WTForms to < 3.2

I reported it to Daniel dpgaspar/Flask-AppBuilder#2276 - we work closely with Daniel and I wll make sure to make him aware of it.

Fixed in FAB 4.5.2