makemessages的Unicode问题——所有Django 1.6.2 Python 3.3

makemessages的Unicode问题——所有Django 1.6.2 Python 3.3,django,python-3.x,unicode,gettext,Django,Python 3.x,Unicode,Gettext,从Python 2.7和Django 1.4升级项目 更新代码后,我们的应用程序将再次运行(在py3中)。 正在从.mo文件中提取翻译 唯一的问题是我们的旧.po文件不能与一起使用 django-admin.py makemessages-a 它展示了一幅可爱的图画 UnicodeDecodeError:“ascii”编解码器无法解码字节… 我们可以第一次运行makemessages,并获取骨架文件。一旦我们将任何非ASCII(ǹ、è等)翻译添加到msgstr值中,makemessages将无法

从Python 2.7和Django 1.4升级项目

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

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

django-admin.py makemessages-a

它展示了一幅可爱的图画

UnicodeDecodeError:“ascii”编解码器无法解码字节…

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

我发现了一个类似问题的bug报告,但是它们又回到了1.3.x版本,但是上面的版本没有


更新,更多信息:

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

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

以下是.po标题(只是从makemessages自动创建的框架):

#一些描述性的标题。
#版权(C)软件包版权所有者的年份
#此文件在与包相同的许可证下分发。
#第一作者,年。
#
#,模糊
msgid“”
msgstr“”
“项目Id版本:包版本\n”
“将Msgid错误报告给:\n”
“罐创建日期:2014-02-28 22:42+0000\n”
“采购订单修订日期:年月日:MI+区域\n”
“最后一个转换器:全名\n”
“语言团队:语言\n”
“语言:\n”
“MIME版本:1.0\n”

“内容类型:文本/普通;字符集=UTF-8\n” “内容传输编码:8位\n” “复数形式:nplurals=2;复数=(n!=1);\n”
这在Python2.7和Django 1.5下以前(相同的文件)是有效的


更新#2

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

可能是提交了一个bug,将进行更新。

这让我很扫兴,因为Py2的一切都很好,但Py3没有问题,所以我认为这就是问题所在

问题的部分原因是我使用Docker,并在容器中运行
makemessages
,该容器没有为bash设置任何特定的区域设置

我尝试过的事情:

  • 使用UTF-8保存文件(带和不带BOM)
  • 确保在
    .po
    文件的头中有
    UTF-8
  • 创建新的空白板岩项目
  • 使用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等(由于我的bash会话没有专门设置语言环境,所以它被设置为ANSI)

回答
在我的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,我就可以):

将其放入
~/.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使用的是环境语言环境,而不是文件/或标题内容类型的编码,这让我措手不及。

字符集标题在.po文件中包含正确的值吗?.po标题中包含的是“Content Type:text/plain;charset=UTF-8\n”。我已经在subprocess.py(stacktrace的一部分)中添加了一些print语句,它的编码是ANSI_X3.4-1968。创建一个带有单个翻译的新项目给我带来了同样的痛苦。使用Py 2.7而不是3.3为什么不将环境变量放入Dockerfile?
# 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=
# locale -a
C
C.UTF-8
POSIX
export LC_ALL=C.UTF-8
export LANG=C.UTF-8
export LANGUAGE=C.UTF-8