IPA provides good gettext abilities implemented in several python classes like ConcatenatedLazyText, Gettext, NGettext.
From documentation:
IPA presents some tricky gettext challenges. On the one hand, most translatable message are defined as class attributes on the plugins, which means these get evaluated at module-load time. But on the other hand, each request to the server can be in a different locale, so the actual translation must not occur till request time.
So, developer marks a translatable text as _() and translation will be performed later upon execution of:
_()
__str__ __json__ __mod__ format
and so on.
Very good idea, but nobody checks which the context is now - may be plugin loading or may be execution of some command.
For example.
ipaserver/plugins/trust.py class trust_add ... StrEnum('range_type?', label=_('Range type'), cli_name='range_type', doc=_('Type of trusted domain ID range, one of {vals}' ).format(vals=', '.join(sorted(range_types))), values=sorted(range_types), ),
Here doc will never be translated to the request's Locale because this message has been translated at loading time by execution of format().
doc
format()
This is an error prone approach. Some runtime/buildtime validation is required to prevent such subtle translation problems.
In order to reproduce: configure language to French on the client
# dnf install glibc-langpack-fr # export LANG=fr_FR.utf8 # export LC_ALL=fr_FR.utf8 # kinit admin # ipa trust-add --help Usage: ipa [global-options] trust-add REALM [options] Add new trust to use. [...] --range-size=INT Taille de la plage d'ID réservée au domaine approuvé --range-type=['ipa-ad-trust', 'ipa-ad-trust-posix'] Type of trusted domain ID range, one of allowed values [...]
The output is mixing french and english.
This doc was fixed at 6f245db and likely french ipa.mo doesn't include updated translation yet (i mean "Type of trusted domain ID range, one of allowed values"). So, right after adding message id and message string to mo there should be no problem.
But if specify previous:
doc=_('Type of trusted domain ID range, one of {vals}').format(vals=', '.join(sorted(range_types))),
this is the case.
Metadata Update from @rcritten: - Issue priority set to: normal - Issue set to the milestone: FreeIPA 4.7.1
Metadata Update from @rcritten: - Issue set to the milestone: FreeIPA 4.7.2 (was: FreeIPA 4.7.1)
FreeIPA 4.7.1 has been released, moving to FreeIPA 4.7.2 milestone
Login to comment on this ticket.