I am trying to i18n/internationalize an existing python django project. That means adding lots of _ to strings in my python code. There are a lot of strings to go through, and it's very likely that I could miss some.

Pylint to the rescue

pylint is a great tool to analyze your python code to find errors. You can also write custom pylint checkers/plugins/modules to check for specific things.

I wrote a pylint plugin to check for all strings that look like they should be translated/i18n'ed, and raise a warning message if they are not.

pylint checker for missing gettext

The package is in PyPI, get it with pip install pylint-i18n .

The code for pylint-i18n is on github. Download missing_gettext.py directly.

To use it, make sure that python module is in your PYTHONPATH (if you used pip, this is all done for you already), and then call pylint link this: pylint --load-plugins=missing_gettext /path/to/python/file.py

How does it work

Pylint walks through the parse tree of your python programme. Everytime it sees a constant, it calls this module. If the constant is a string, and the value has not been whitelisted, then this module walks up the parse tree from this string. At each point it checks if the current node in the tree is a call to _ , ugettext or ugettext_lazy . If so, then this string has been translated, and is OK. It also checks if the current position is one of the whitelisted structures (e.g. is it a call to the django logging method), if so, it ignores this string.

If none of these checks pass, then the string is assumed to be bad, and pylint attaches a warning message to it

Examples

Input

print "Hello"

Output

test.py:1: [W] non-gettext-ed string 'Hello'

Input

def something(arg): """This is a function""" return arg['some']

Output

(No output because nothing needs translating)

Input

def something(arg): """This is a function""" return "Somestring %d" % arg['some']

Output

test.py:3: [W, something] non-gettext-ed string 'Somestring %d'

Input

def something(arg): """This is a function""" return "Somestring %d" % arg['some'] def another(): print "Hello again"

Output

test.py:3: [W, something] non-gettext-ed string 'Somestring %d' test.py:6: [W, another] non-gettext-ed string 'Hello again'

Whitelisted text

The first time I ran this is caught loads of text that wasn't passed through gettext, such as dictionary['key'] access. The current code has several checks, based on the value of the string, or the location of the string in the source code, that can make a potentially untranslated string be ignored. e.g. if the string is empty, the string is the key in a dictionay, etc., then ignore it.

These ignore-rules are tailored to my django project, you may want to change them to suit your django project, or if you are not using it for a django project, you should disable them.

Todo

Make a proper python package and upload to PyPI.

Add options to disable the django-specific checks so it can work well on non-django projects.

It's currently using warning message id W9903 , since that one is free, I'm not sure this is the best way.

Download

The code for pylint-i18n is on github. Download missing_gettext.py directly.

Mentions/Backlinks