Python – bug in “django-admin.py makemessages” or xgettext call? -> “warning: unterminated string”

djangointernationalizationpythonxgettext

django-admin.py makemessages dies with errors "warning: unterminated string" on cases where really long strings are wrapped:

string = "some text \
          more text\
          and even more"

These strings don't even need to be translated – e.g. sql query strings.
The problem goes away when I concatenate the string, but the result looks ugly and it takes time to join them…

Does anyone have a problem like this? Have you found a way to fix it?

I have the following versions of the tools involved:

xgettext-0.17, gettext-0.17, django-1.0.2, python-2.6.2

There was a ticket on this issue, but it was closed probably because the error appears only in some combination of component versions.

EDIT: found the source of problem – xgettext prints warning messages to sterr and django takes them as fatal errors and quits.

return status of xgettext call is 0 – "success". I guess that django should recognize it as success and not quit because of warnings.

Interestinly xgettext still extracts backslash-wrapped strings if they need to be translated, but gives warnings in stderr ("unterminated string") and .po file ("internationalized messages should not contain the `\r' escape sequence")

xgettext call is the following:

xgettext -d django -L Python --keyword=gettext_noop \
         --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 \
         --keyword=ugettext_noop --keyword=ugettext_lazy \
         --keyword=ungettext_lazy:1,2 
         --from-code UTF-8 -o - source_file.py

called from django/core/management/commands/makemessages.py

Best Solution

I can think of two possibilities: you might have an extra space after your backslash at the end of the line; or you might be somehow ending up with the wrong line-ending characters in your source (e.g. Windows-style when your Python is expecting Unix-style, thus disabling the backslashes).

Either way, I would take advantage of C-style automatic string concatenation:

>>> string = ("some text "
...           "more text "
...           "and even more")
>>> string
'some text more text and even more'

Alternatively, if you don't mind newlines ending up in there, use multi-line strings:

>>> string = """some text
...             more text
...             and even more"""

IMO these look much nicer, and are much less fragile when refactoring.

Does this help?