Skip to content

translation-positional-used (ODOO042)

Preview (since 0.16.2.2) · 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 translated format strings with two or more positional placeholders (_("%s %s") or _("{} {}")).

Why is this bad?

Translators can't reorder positional placeholders, but many languages need a different word order. Named placeholders (%(name)s, {name}) keep the translation reorderable.

Example

_("%s of %s") % (count, total)

Use instead:

_("%(count)s of %(total)s") % {"count": count, "total": total}

Fix safety

A fix is offered when the values are passed as arguments of the translation call itself and a name can be derived for each one, e.g. self.env._("%s of %s", count, tier.name) becomes self.env._("%(count)s of %(tier_name)s", count=count, tier_name=tier.name). Dotted attribute chains join with underscores (tier.name becomes tier_name), and calls or subscripts borrow the most meaningful identifier inside them (", ".join(fields_string) becomes fields_string, values[0] becomes values_0).

When the rewritten call no longer fits within the configured line length, the fix expands it with one argument per line, wrapping the term itself into a parenthesized implicit string concatenation if needed.

The fix is marked unsafe because it changes the source translation term: existing translations keyed on the old term (in .po files) no longer match and must be re-exported and re-translated.