Comment 9 for bug 409785

Revision history for this message
David Planella (dpm) wrote :

Sorry to comment on a closed bug, but I just wanted to mention this here for the record.

* In C, due to what Colin was mentioning, that is, the ability to discard named arguments in format strings, you can translate plurals such as:

#, c-format
msgid "%d package"
msgid_plural "%d packages"
msgstr[0] "one package"
msgstr[1] "%d packages"

This will work in the program and "msgfmt --check" won't show any errors

* In Python, you cannot do this. Python supports unnamed (e.g. %d) and named (e.g. %(package)d) arguments in format strings. With unnamed arguments, Python verifies that all of the arguments are being used.

#, python-format
msgid "%d package"
msgid_plural "%d packages"
msgstr[0] "one package"
msgstr[1] "%d packages"

This will cause a program crash. However, "msgfmt --check" won't show any errors either. That's why Launchpad does not detect these errors, since it uses the standard gettext tools for error-checking.

The workaround to this in the code is simply to use always named arguments for plurals in Python.

For translators, this means that they can translate the following without causing a program crash:

#, python-format
msgid "%(package)d package"
msgid_plural "%(package)d packages"
msgstr[0] "one package"
msgstr[1] "%(package)d packages"

For developers to implement this, they can use something like:

gettext.ngettext("%(package)d package", "%(package)d packages", countInstall) % { 'package': countInstall}

instead of:

gettext.ngettext("%d package", "%d packages", countInstall) % countInstall

This also offers the benefit that if there are several arguments in the same string, naming them permits rearranging them in the translation, which is otherwise not possible in Python.