translation-not-lazy (ODW8301)
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.
The rule only applies from Odoo 14.0 on, the version whose translation functions take
the interpolation arguments themselves; up to 13.0 translation-contains-variable
covers the eager interpolation instead. Configure the version with the odoo-version
setting; without it the rule stays enabled.
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.