Skip to content

[rejected AI] Fix i18n silently disabled when Flask-Babel isn't installed - #703

Closed
cristianchiriac wants to merge 1 commit into
pallets-eco:mainfrom
cristianchiriac:fix/i18n-fallback-without-babel
Closed

cristianchiriac wants to merge 1 commit into
pallets-eco:mainfrom
cristianchiriac:fix/i18n-fallback-without-babel

Conversation

@cristianchiriac

Copy link
Copy Markdown

Fixes #582.

Bug

Plain wtforms.Form works out of the box with meta={"locales": [...]}, no Flask-Babel needed:

form = wtforms.Form(flask.request.form, meta={"locales": ["fr"]})

But the same configuration on a FlaskForm silently produces English error messages unless Flask-Babel is installed and initialized:

form = FlaskForm(flask.request.form, meta={"locales": ["fr"]})

FlaskForm.Meta.get_translations() is the reason:

def get_translations(self, form):
    if not current_app.config.get("WTF_I18N_ENABLED", True):
        return super().get_translations(form)
    return translations

translations (imported from flask_wtf.i18n) is None whenever Flask-Babel isn't installed — caught as an ImportError in flask_wtf/form.py. With WTF_I18N_ENABLED at its default (True), this method returns that None unconditionally, discarding the form's own meta.locales-based translations entirely, instead of falling back to WTForms' own translation machinery the way the WTF_I18N_ENABLED=False branch already does.

Fix

Also fall back to super().get_translations(form) when translations is None.

Test plan

  • Added test_i18n_falls_back_without_babel, monkeypatching flask_wtf.form.translations to None (deterministic regardless of whether Flask-Babel happens to be installed in the CI matrix) and asserting a meta.locales-configured form still gets localized errors.
  • Verified the test fails with the exact reported behavior (English message instead of the Spanish one) against the unpatched code, and passes after the fix.
  • Reproduced the issue's own example directly (French vs English) against both the unpatched and patched code, with and without Flask-Babel actually installed.
  • pytest tests/ — 84 passed (up from 80), 2 skipped (unchanged) with Flask-Babel installed; ran the full suite both with and without Flask-Babel present.
  • ruff check / ruff format --check — clean.
  • Added a changelog entry per CONTRIBUTING.rst.

Fixes pallets-eco#582. FlaskForm.Meta.get_translations() unconditionally
returned "translations" unless WTF_I18N_ENABLED was explicitly set to
False. "translations" is set to None when Flask-Babel isn't installed
(caught ImportError in flask_wtf/form.py), so any form using
meta={"locales": [...]} without Flask-Babel silently got no
translations at all, even though plain wtforms.Form with the exact
same meta.locales configuration works out of the box.

Fall back to WTForms own translations (super().get_translations)
whenever "translations" is None, the same way the WTF_I18N_ENABLED=False
path already does, instead of returning None.
@davidism

Copy link
Copy Markdown
Member

@davidism davidism closed this Sep 17, 2026
@davidism davidism changed the title Fix i18n silently disabled when Flask-Babel isn't installed [rejected AI] Fix i18n silently disabled when Flask-Babel isn't installed Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

flask-wtf i18n does not work without flask-babel

2 participants