【问题标题】:Unicode issue with makemessages --all Django 1.6.2 Python 3.3makemessages 的 Unicode 问题 --all Django 1.6.2 Python 3.3
【发布时间】:2014-04-02 03:22:51
【问题描述】:

Python 2.7 -> 3.3.1Django 1.4 -> 1.6.2 升级项目.

更新代码后,我们的应用程序再次运行(在 py3 中)
正在从 .mo 文件中提取翻译。

唯一的问题是我们的旧 .po 文件不能与

一起使用

django-admin.py makemessages -a

它显示了一个可爱的

UnicodeDecodeError: 'ascii' codec can't decode byte...

我们可以第一次运行makemessages,得到骨架文件。一旦我们将任何非 ASCII 翻译(ǹ、è 等)添加到 msgstr 值,makemessages 将无法完成。
(如果我们运行带有任何 NON 的更高详细度模板的 makemessages -ASCII 字符被跳过。)

我发现了类似问题的错误报告,但它们又回到了 1.3.x 版本中,但对于上述版本没有任何实际意义。


更新,更多信息:

这是发生异常的地方:
../python3.3/subprocess.py 第 847 行

def _translate_newlines(self, data, encoding):
    data = data.decode(encoding)
    return data.replace("\r\n", "\n").replace("\r", "\n")

encoding 的值为ANSI_X3.4-1968。我已将模板文件与 .po 文件一起保存为 UTF-8。

这是 .po 标头(只是从 makemessages 自动创建的骨架)

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-02-28 22:42+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"  

这在 Python 2.7 和 Django 1.5 之前(相同的文件)有效


更新 #2

  • 列表项
  • 新建了一个裸项目(django-admin.py startproject blah)
  • 启用 i18n 等
  • 创建了一个翻译(就在 settings.py 中)
  • 运行`makemessages -l de
  • Py2.7 (#python manage.py makemessages -a) 按预期工作
  • Py3.3 (#python3 manage.py makemessages -a) 失败

可能会提交错误,将更新。

【问题讨论】:

  • 字符集标题是否包含 .po 文件中的正确值?
  • "Content-Type: text/plain; charset=UTF-8\n" 是 .po 标头中的内容。我在 subprocess.py (堆栈跟踪的一部分)中添加了一些打印语句,它得到了 ANSI_X3.4-1968 的编码
  • 用一个翻译创建一个新项目给我同样的悲痛。适用于 Py 2.7,而不是 3.3

标签: django python-3.x unicode gettext


【解决方案1】:

这让我失望了,因为 Py2 一切都很好,但 Py3 却不行,所以我认为这就是问题所在。

问题的部分原因是我正在使用 Docker,并在容器内运行 makemessages,该容器没有将语言环境设置为任何特别用于 bash 的内容。

我尝试过的事情:

  • 使用 UTF-8 保存文件(有和没有 BOM)
  • 确保 UTF-8.po 文件的标题中
  • 创建一个新的空白项目
  • 使用 Py3 重新创建所有 .po 文件(因为它们最初是使用 Py2 创建的)

第 847 行的 subprocess.py 中抛出了最上面的异常:

def _translate_newlines(self, data, encoding):
    data = data.decode(encoding)
    return data.replace("\r\n", "\n").replace("\r", "\n")

传入的编码是ANSI_X3.4-1968,这很奇怪,因为我将文件保存为 UTF-8 等 (它被设置为 ANSI...由于我的 bash 会话没有设置语言环境具体来说)

回答
在我的 Docker 容器中,我没有在终端中设置区域设置,所以它们是:

# locale
LANG=
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=

这些是我可用的语言环境(缺少我的特定语言环境,en_US.UTF-8,但只要是 UTF-8 就可以)

# locale -a
C
C.UTF-8
POSIX

把它放在~/.bashrc

export LC_ALL=C.UTF-8
export LANG=C.UTF-8
export LANGUAGE=C.UTF-8  

现在我得到UTF-8 作为subprocess.py 中的内容类型,一切都适用于Py3/Django1.6 =)

长话短说,Django/subprocess.py 使用的是环境语言环境,而不是文件/或标头 Content-Type 的编码,这让我措手不及。

【讨论】:

  • 为什么不将环境变量放入 Dockerfile 中?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-24
  • 1970-01-01
相关资源
最近更新 更多