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

时间:2014-02-28 22:09:02

标签: django python-3.x unicode gettext

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

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

唯一的问题是我们旧的 .po 文件无法与

一起使用

django-admin.py makemessages -a

它显示了一个可爱的

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

我们可以第一次运行makemessages并获取骨架文件。一旦我们将任何非ASCII(ǹ,è等)的翻译添加到msgstr值,makemessages就无法完成。
(如果我们运行带有更高详细程度模板的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。我已经将模板文件保存为UTF-8以及.po文件。

这是.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中)
  • Ran`makemessages -l de
  • Py2.7(#python manage.py makemessages -a)按预期工作
  • Py3.3(#python3 manage.py makemessages -a)失败

可能提交错误,将更新。

1 个答案:

答案 0 :(得分:9)

这让我失望,因为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的编码。

相关问题