translation-not-lazy (ODOO059)
Preview (since 0.16.2.9) · Related issues · View source
Derived from the odoo linter.
Fix is sometimes available.
This rule is unstable and in preview. The --preview flag is required for use.
What it does
Checks for translation calls that interpolate values eagerly with the % operator or
string concatenation (_("Hello %s") % name, _("Hello %s" % name),
_("Hello " + name)) instead of passing them as arguments to the translation
function.
Why is this bad?
Since Odoo 14.0 the translation functions (_, self.env._) interpolate the values
themselves: _("Hello %s", name). Interpolating before the call translates the
already-interpolated text, so the term never matches the exported translation entry.
Interpolating after the call works, but bypasses Odoo's own interpolation and, for
lazy translations, forces the evaluation at definition time instead of rendering time.
Example
Use instead:
Fix safety
A fix is offered when the interpolated values can be moved into the translation call
faithfully: a tuple becomes positional arguments (_("%s %s") % (a, b) becomes
_("%s %s", a, b)), a dict literal with valid identifier keys becomes keyword
arguments (_("%(name)s") % {"name": name} becomes _("%(name)s", name=name)), and
any other single value becomes one positional argument when the term only uses
positional placeholders.
The fix is marked unsafe because it relies on the translation-function signature
introduced in Odoo 14.0, and because a function named _ that is not Odoo's
translation function (e.g. gettext.gettext) does not accept the extra arguments.