Gettext fallbacks don't work with untranslated strings

拥有回忆 提交于 2020-01-05 12:45:55

问题


In source code of my application I wrapped with gettext strings in russian, so this is my default language and *.po files based on it. Now I need to make fallbacks chain - string that doesn’t translated in spanish catalog should be searched in english catalog and than if it doesn’t translated will be returned itself in russian.

I trying to do this with add_fallback method, but untranslated strings in self._catalog of GNUTranslations(NullTranslations) already replaced with itself and ugettext method never doing fallbacks.

What I am doing wrong?

Example:

Current locale is Spanish, and we’ve got no translations for string "Титул должен быть уникальным" in Spanish catalog and as a result "Title should be unique" from English catalog should be returned.

Spanish *.po file

msgid "Титул должен быть уникальным"
msgstr "" # <— We've got no translation for this string

English *.po file

msgid "Титул должен быть уникальным"
msgstr "Title should be unique"

Russian *.po file does not contains translations, because this language used as keys in source code (default language)

msgid "Титул должен быть уникальным"
msgstr ""

I’ve got Spanish translator (object of GNUTranslations), and I add English traslator (object of GNUTranslations) as fallback for it with add_fallback method. So, my es_translator._fallback is en_translator object.

In ugettext function we trying to get value from self._catalog by message as key, and only if it is missing we doing self._fallback call. But self._catalog.get(message) for untranslated string return string itself. self._catalog["Титул должен быть уникальным"] -> "Титул должен быть уникальным" and we never doing search in English catalog.

def add_fallback(self, fallback):
    if self._fallback:
        self._fallback.add_fallback(fallback)
    else:
        self._fallback = fallback

def ugettext(self, message):
        missing = object()
        tmsg = self._catalog.get(message, missing)
        if tmsg is missing:
            if self._fallback:
                return self._fallback.ugettext(message)
            return unicode(message)
        return tmsg

However if message marked as fuzzy it does’t include in self._catalog and fallback works well.

#, fuzzy
msgid "Отсутствуют файлы фотографий"
msgstr "Archivos de fotos ausentes"

回答1:


Ok, python is doing something different from the standard fallback mechanism for added functionality which is not working like you think it should. This may warrant a bug report.

The standard fallback mechanism only has one fall back if a string is not in a translation: use the source string. In most cases this is english (the C or POSIX locale forces no lookups), but in your case because the messages in the source the C locale has russian text (which may cause other problems because sometimes the C locale assumes ascii not utf8). The current recommended best practice is to use english in the C locale encoded in seven bit ascii and then translate to all other languages. This is a significant redesign (and admittedly anglocentric) but unless someone improves the tools (which would be even more significant redesign) this is probably your best bet.




回答2:


Only way to solve it was removing untranslated strings while compiling *.mo files. Patch babel/messages/mofile.py write_mo with

messages = [m for m in messages if m.string]


来源:https://stackoverflow.com/questions/29367405/gettext-fallbacks-dont-work-with-untranslated-strings

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!