A Custom Pylint Check For i18n Keys

plapadoo
plapadoo
Published in
2 min readSep 18, 2019

Using a programming language with a dynamic type system is convenient. But convenience comes at a price. As there is no compiler to detect typos and other trivial mistakes, bigger programs written in dynamic languages like Python often suffer from bugs which could be avoided easily by using a strong type system. To avoid these problems, we are using Python type hints, mypy, Pylint and other tools. This tooling catches most typos and other programming mistakes. However, typos in translation keys won’t get caught.

Translate All The Texts

For python, gettext seems to be a popular choice when doing translations. gettext is a great choice when managing a lot of translated text. However, since we don’t have a lot of text in our small video game reaktron, we decided to use a lightweight lib called python-i18n there. As most i18n solutions, it works by specifying a key-value-pair in a file which maps from translation keys to translations:

{
...
“quit”: “Terminar”,
...
}

Whenever a text should be loaded in a program, the translation key is specified and the library loads the correct translation for the current language:

i18n.t("ui.quit")

Typos Screw it up

This works perfectly as long as the translation keys you specify in your program are correct. python-i18n can be configured to raise an exception when a translation key does not exist. However, it will only raise at runtime which doesn’t help much since we like to detect our bugs before the user does. Python type hints and the tooling mentioned above don’t catch typos in translations keys because these keys look like regular strings to any tool unaware of python-i18n.

Custom Pylint Checks

Fortunately, Pylint can easily be extended by custom checks. Here is a check to detect typos in translations keys:

https://gist.github.com/krinnewitz/8d4581ca32989e20771c300ab07d88f1

This check can be loaded by adding load-plugins=checks.i18n_check to the .pylintrc file, given the i18n_check.pyfile is placed in a folder called checks. If this check is used, Pylint will validate all occurrences of i18n.t("my.translationskey")and show a warning if a translation key does not exist.

--

--