ugettext and ugettext_lazy functions not recognized by makemessages in Python Django
Question: I'm working with Django 1.5.1 and I'm experiencing some "strange behaviour"
with translations. I'm using `ugettext` and `ugettext_lazy` in the same Python
file. If I organize the imports as:

    
    
    from django.utils.translation import ugettext as trans
    from django.utils.translation import ugettext_lazy as _
    

or

    
    
    from django.utils.translation import ugettext as trans, ugettext_lazy as _
    

The strings marked as `trans("string")` are skipped when running
`makemessages` command.

However, if I don't rename the `ugettext` it works well with both versions:

    
    
    from django.utils.translation import ugettext
    from django.utils.translation import ugettext_lazy as _
    

or

    
    
    from django.utils.translation import ugettext, ugettext_lazy as _
    

Now `trans("string")` works well.

**So, does anybody know why this import renaming is causing the renamed
function not to be called?** Is this an actual Python "limitation" I didn't
know when renaming more than one function inside the same module?

* * *

**UPDATE**

After some testing, I've realized that even creating an empty python module
inside an app with the following code it doesn't work:

    
    
    from django.utils.translation import ugettext_lazy as translate
    
    a = translate("string")
    

However, if using `_` for the alias it works:

    
    
    from django.utils.translation import ugettext_lazy as _
    
    a = _("string")
    

My **conclusion** is: _You can only use the`_` alias for `ugettext` and
`ugettext_lazy` (or any other related translation function) in Django or else
it won't be recognized by `makemessages` command_. The technical explanation
can be found in Robert Lujo's answer.

Thanks!


Answer: Django command utility makemessages internally calls
[xgettext](https://www.gnu.org/savannah-
checkouts/gnu/gettext/manual/html_node/xgettext-Invocation.html) program like
this:

    
    
    cmd = (
        'xgettext -d %s -L Python %s %s --keyword=gettext_noop '
        '--keyword=gettext_lazy --keyword=ngettext_lazy:1,2 '
        '--keyword=ugettext_noop --keyword=ugettext_lazy '
        '--keyword=ungettext_lazy:1,2 --keyword=pgettext:1c,2 '
        '--keyword=npgettext:1c,2,3 --keyword=pgettext_lazy:1c,2 '
        '--keyword=npgettext_lazy:1c,2,3 --from-code UTF-8 '
        '--add-comments=Translators -o - "%s"' %
        (domain, wrap, location, work_file))
    

(source can be found
[here](https://github.com/django/django/blob/master/django/core/management/commands/makemessages.py#L98)).
So, some keywords are predefined by the
[xgettext](https://www.gnu.org/savannah-
checkouts/gnu/gettext/manual/html_node/xgettext-Invocation.html) utility
(check reference for --keyword):

  * for python - gettext, ugettext, dgettext, ngettext, ungettext, dngettext, _

and some are added by django utility:

  * gettext_lazy , ngettext_lazy , ugettext_noop , ugettext_lazy , ungettext_lazy , pgettext , npgettext , pgettext_lazy , npgettext_lazy

Keyword **trans** is not in any of these keyword sets, so you should not use
it for marking texts for translations.

