【问题标题】:Python xgettext merges gettext and ngettext strings, breaking translation lookupPython xgettext 合并 gettext 和 ngettext 字符串,打破翻译查找
【发布时间】:2012-10-26 05:49:54
【问题描述】:

跑步:

> xgettext test.py -o out.pot

关于 Python sn-p test.py:

def main(num):
    gettext("TEST")
    ngettext(num, "TEST", "TESTS")

生成具有以下行的pot文件(翻译的字符串在po文件中):

#: test.py:3 test.py:4
msgid "TEST"
msgid_plural "TESTS"
msgstr[0] "TEST-SINGLE"
msgstr[1] "TEST-PLURAL"

将其转换为 po 文件,然后是 mo 文件。我无法获得 gettest("TEST") 调用的翻译。

> ngettext("TEST", "TESTS", 1)
> TEST-SINGLE
> gettext("TEST")
> TEST

我正在使用 Python 的标准 gettext 包。我不确定这些合并行为是否是预期的,但它似乎破坏了查找非复数字符串的翻译的能力。有没有办法避免这种情况?

我正在考虑为 gettext 创建一个后备,如果第一个调用失败,则尝试使用 ngettext 调用。不过这看起来很 hacky。

【问题讨论】:

  • [删除了这个,因为我想出了如何回答我自己的问题]

标签: python internationalization gettext extraction


【解决方案1】:

问题似乎源于 gettext 包查找翻译的方式。对于 gettext 和 ugettext 调用,它只是在目录中查找 _catalog['TEST'],而不搜索 _catalog[("TEST", 0)]。

我不认为这是正确的行为,因为 xgettext 决定合并这两个字符串,但我在文档中找不到任何东西来证明一种或另一种方式。

为了解决这个问题,我在 gettext 和 ugettext 的两种替换方法中进行猴子修补,如果简单查找失败,它将回退到 (message, 0) 目录查找。

【讨论】:

  • 当我运行 xgettext test.py -o test.pot 时。我得到以下结果:
【解决方案2】:

这两个条目完全相同,即单数条目与复数条目相同。演示:

msgid "Test"
msgstr "Toets"

msgid "Test"
msgid_plural "Tests"
msgstr[0] "Toets"
msgstr[1] "Toetse"

然后使用 msgfmt 编译:

msgfmt test.po 
bob.po:4: duplicate message definition...
bob.po:2: ...this is the location of the first definition
msgfmt: found 1 fatal error

Gettext 使用 msgid 作为字符串的键,因此它会看到这些单数和复数字符串是重复的。

【讨论】:

  • 当我运行 xgettext test.py -o test.pot 时。我得到以下结果: #: test.py:25 test.py:26 msgid "TEST" msgid_plural "TESTS" msgstr[0] "" msgstr[1] "
  • 这会向我暗示 gettext 打算将它们合并。如果您决定在程序中添加一个 ngettext("test", "tests", num) 调用,则必须更新每个 gettext("test") ,这不是很用户友好。
  • 它打算将它们合并,因为它们与 Gettext 完全相同,正如我上面所说的。为了消除歧义,老实说,您的翻译人员可能需要它,您需要使用 pgettext 它将提供允许消除歧义的 msgctxt 条目。查找键为“msgctxt+msgid”,这将使这些条目唯一。
【解决方案3】:

我在最近的一个项目中遇到了同样的问题。在我看来,这可能被认为是 python gettext 模块中的一个错误。自 2013 年以来,Python bugtracker 上有 an open issue for this,因此其他人也有同样的看法……我提出了 a patch,但它可能需要一段时间才能包含在发布中。

当然,使用ngettext("TEST", "TESTS", 1) 而不是ngettext("TEST") 是一个非常简单的解决方法。不完全令人满意,但它确实有效......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    • 2012-09-13
    相关资源
    最近更新 更多