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.

Reply via email to