Author: ramiro Date: 2010-10-10 11:38:28 -0500 (Sun, 10 Oct 2010) New Revision: 14125
Added: django/trunk/tests/regressiontests/makemessages/compilation.py django/trunk/tests/regressiontests/makemessages/locale/es_AR/ django/trunk/tests/regressiontests/makemessages/locale/es_AR/LC_MESSAGES/ django/trunk/tests/regressiontests/makemessages/locale/es_AR/LC_MESSAGES/django.po Modified: django/trunk/django/core/management/commands/compilemessages.py django/trunk/docs/topics/i18n/localization.txt django/trunk/tests/regressiontests/makemessages/tests.py Log: Fixed #6073 -- Made compilemessages 18n management command reject PO files with BOM. Modified: django/trunk/django/core/management/commands/compilemessages.py =================================================================== --- django/trunk/django/core/management/commands/compilemessages.py 2010-10-10 10:02:18 UTC (rev 14124) +++ django/trunk/django/core/management/commands/compilemessages.py 2010-10-10 16:38:28 UTC (rev 14125) @@ -1,3 +1,4 @@ +import codecs import os import sys from optparse import make_option @@ -3,5 +4,12 @@ from django.core.management.base import BaseCommand, CommandError -def compile_messages(locale=None): +def has_bom(fn): + f = open(fn, 'r') + sample = f.read(4) + return sample[:3] == '\xef\xbb\xbf' or \ + sample.startswith(codecs.BOM_UTF16_LE) or \ + sample.startswith(codecs.BOM_UTF16_BE) + +def compile_messages(stderr, locale=None): basedirs = [os.path.join('conf', 'locale'), 'locale'] if os.environ.get('DJANGO_SETTINGS_MODULE'): @@ -21,8 +29,11 @@ for dirpath, dirnames, filenames in os.walk(basedir): for f in filenames: if f.endswith('.po'): - sys.stderr.write('processing file %s in %s\n' % (f, dirpath)) - pf = os.path.splitext(os.path.join(dirpath, f))[0] + stderr.write('processing file %s in %s\n' % (f, dirpath)) + fn = os.path.join(dirpath, f) + if has_bom(fn): + raise CommandError("The %s file has a BOM (Byte Order Mark). Django only supports .po files encoded in UTF-8 and without any BOM." % fn) + pf = os.path.splitext(fn)[0] # Store the names of the .mo and .po files in an environment # variable, rather than doing a string replacement into the # command, so that we can take advantage of shell quoting, to @@ -49,4 +60,4 @@ def handle(self, **options): locale = options.get('locale') - compile_messages(locale) + compile_messages(self.stderr, locale=locale) Modified: django/trunk/docs/topics/i18n/localization.txt =================================================================== --- django/trunk/docs/topics/i18n/localization.txt 2010-10-10 10:02:18 UTC (rev 14124) +++ django/trunk/docs/topics/i18n/localization.txt 2010-10-10 16:38:28 UTC (rev 14125) @@ -188,6 +188,12 @@ ``django-admin compilemessages`` works see :ref:`gettext_on_windows` for more information. +.. admonition:: .po files: Encoding and BOM usage. + + Django only supports ``.po`` files encoded in UTF-8 and without any BOM + (Byte Order Mark) so if your text editor adds such marks to the beginning of + files by default then you will need to reconfigure it. + .. _creating-message-files-from-js-code: Creating message files from JavaScript source code Added: django/trunk/tests/regressiontests/makemessages/compilation.py =================================================================== --- django/trunk/tests/regressiontests/makemessages/compilation.py (rev 0) +++ django/trunk/tests/regressiontests/makemessages/compilation.py 2010-10-10 16:38:28 UTC (rev 14125) @@ -0,0 +1,35 @@ +import os +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +from django.core.management import CommandError +from django.core.management.commands.compilemessages import compile_messages +from django.test import TestCase + +LOCALE='es_AR' + + +class MessageCompilationTests(TestCase): + + MO_FILE='locale/%s/LC_MESSAGES/django.mo' % LOCALE + + def setUp(self): + self._cwd = os.getcwd() + self.test_dir = os.path.abspath(os.path.dirname(__file__)) + + def tearDown(self): + os.chdir(self._cwd) + + +class PoFileTests(MessageCompilationTests): + + def test_bom_rejection(self): + os.chdir(self.test_dir) + # We don't use the django.core.management intrastructure (call_command() + # et al) because CommandError's cause exit(1) there. We test the + # underlying compile_messages function instead + out = StringIO() + self.assertRaises(CommandError, compile_messages, out, locale=LOCALE) + self.failIf(os.path.exists(self.MO_FILE)) Added: django/trunk/tests/regressiontests/makemessages/locale/es_AR/LC_MESSAGES/django.po =================================================================== --- django/trunk/tests/regressiontests/makemessages/locale/es_AR/LC_MESSAGES/django.po (rev 0) +++ django/trunk/tests/regressiontests/makemessages/locale/es_AR/LC_MESSAGES/django.po 2010-10-10 16:38:28 UTC (rev 14125) @@ -0,0 +1,20 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <em...@address>, YEAR +# +msgid "" +msgstr "" +"Project-Id-Version: Django\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2010-01-05 20:25-0300\n" +"PO-Revision-Date: 2010-02-22 00:14-0300\n" +"Last-Translator: Translator <transla...@example.com>\n" +"Language-Team: Django-I18N <t...@example.com>\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" + +#: path/file.py:1 +msgid "This file has a UTF-8 BOM an should be rejected by the Django makemessages command." +msgstr "" Modified: django/trunk/tests/regressiontests/makemessages/tests.py =================================================================== --- django/trunk/tests/regressiontests/makemessages/tests.py 2010-10-10 10:02:18 UTC (rev 14124) +++ django/trunk/tests/regressiontests/makemessages/tests.py 2010-10-10 16:38:28 UTC (rev 14125) @@ -38,3 +38,6 @@ if xversion >= (0, 15): from extraction import * del p + +if find_command('msgfmt'): + from compilation import * -- You received this message because you are subscribed to the Google Groups "Django updates" group. To post to this group, send email to django-upda...@googlegroups.com. To unsubscribe from this group, send email to django-updates+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-updates?hl=en.