launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #26267
[Merge] ~cjwatson/launchpad:py3-parse-po-file-content-bytes into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:py3-parse-po-file-content-bytes into launchpad:master.
Commit message:
Parse PO file content as bytes
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/397817
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:py3-parse-po-file-content-bytes into launchpad:master.
diff --git a/lib/lp/translations/interfaces/translationimporter.py b/lib/lp/translations/interfaces/translationimporter.py
index 7547050..10f3775 100644
--- a/lib/lp/translations/interfaces/translationimporter.py
+++ b/lib/lp/translations/interfaces/translationimporter.py
@@ -15,6 +15,7 @@ __all__ = [
'TranslationFormatInvalidInputError',
]
+import six
from zope.interface import Interface
from zope.schema import (
Bool,
@@ -83,9 +84,10 @@ class TranslationFormatBaseError(TranslationImportExportBaseException):
else:
text = default_message
- return "%s%s" % (location_prefix, text)
+ return u"%s%s" % (location_prefix, text)
+@six.python_2_unicode_compatible
class TranslationFormatSyntaxError(TranslationFormatBaseError):
"""A syntax error occurred while parsing a translation file."""
@@ -93,6 +95,7 @@ class TranslationFormatSyntaxError(TranslationFormatBaseError):
return self.represent("Unknown syntax error")
+@six.python_2_unicode_compatible
class TranslationFormatInvalidInputError(TranslationFormatBaseError):
"""Some fields in the parsed file contain bad content."""
diff --git a/lib/lp/translations/utilities/doc/gettext_po_parser.txt b/lib/lp/translations/utilities/doc/gettext_po_parser.txt
index f2f63bb..8ce9e60 100644
--- a/lib/lp/translations/utilities/doc/gettext_po_parser.txt
+++ b/lib/lp/translations/utilities/doc/gettext_po_parser.txt
@@ -14,7 +14,7 @@ The PO parser handles GNU gettext format human readable files.
PO files with empty headers are not allowed.
>>> parser = POParser()
- >>> parser.parse('msgid "foo"\nmsgstr ""\n')
+ >>> parser.parse(b'msgid "foo"\nmsgstr ""\n')
... # doctest: +IGNORE_EXCEPTION_MODULE_IN_PYTHON2
Traceback (most recent call last):
...
@@ -22,8 +22,8 @@ PO files with empty headers are not allowed.
PO files with context after msgids are reported as broken.
- >>> parser.parse('msgid ""\nmsgstr ""\n'
- ... 'msgid "blah"\nmsgctxt "foo"\nmsgstr "bar"\n')
+ >>> parser.parse(b'msgid ""\nmsgstr ""\n'
+ ... b'msgid "blah"\nmsgctxt "foo"\nmsgstr "bar"\n')
... # doctest: +IGNORE_EXCEPTION_MODULE_IN_PYTHON2
Traceback (most recent call last):
...
@@ -31,9 +31,9 @@ PO files with context after msgids are reported as broken.
And a msgctxt followed by msgctxt is caught as well.
- >>> parser.parse('msgid ""\nmsgstr ""\n'
- ... 'msgctxt "foo"\nmsgctxt "foo1"\n'
- ... 'msgid "blah"\nmsgstr "bar"\n')
+ >>> parser.parse(b'msgid ""\nmsgstr ""\n'
+ ... b'msgctxt "foo"\nmsgctxt "foo1"\n'
+ ... b'msgid "blah"\nmsgstr "bar"\n')
... # doctest: +IGNORE_EXCEPTION_MODULE_IN_PYTHON2
Traceback (most recent call last):
...
@@ -42,8 +42,8 @@ And a msgctxt followed by msgctxt is caught as well.
When a string is followed by non-string, non-space data, it is caught
as an error.
- >>> parser.parse('msgid ""\nmsgstr "something"\n'
- ... '"foo" whatever\n')
+ >>> parser.parse(b'msgid ""\nmsgstr "something"\n'
+ ... b'"foo" whatever\n')
... # doctest: +IGNORE_EXCEPTION_MODULE_IN_PYTHON2
Traceback (most recent call last):
...
@@ -51,7 +51,7 @@ as an error.
Unrecognized escape sequences are caught as well.
- >>> parser.parse('msgid "\!"\nmsgstr ""\n')
+ >>> parser.parse(b'msgid "\!"\nmsgstr ""\n')
... # doctest: +IGNORE_EXCEPTION_MODULE_IN_PYTHON2
Traceback (most recent call last):
...
@@ -59,7 +59,7 @@ Unrecognized escape sequences are caught as well.
Unclosed strings (missing closing quotes) are caught.
- >>> parser.parse('msgid ""\nmsgstr "\n')
+ >>> parser.parse(b'msgid ""\nmsgstr "\n')
... # doctest: +IGNORE_EXCEPTION_MODULE_IN_PYTHON2
Traceback (most recent call last):
...
@@ -283,7 +283,7 @@ template.
Parsing a PO template:
- >>> content = """
+ >>> content = b"""
... msgid ""
... msgstr ""
... "Project-Id-Version: Foobar 1.0\\n"
@@ -312,7 +312,7 @@ PO templates, and other PO files that do not specify their encoding,
are parsed as UTF-8 text. If they contain non UTF-8 characters, parsing
errors occur:
- >>> chunk2 = """
+ >>> chunk2 = b"""
... #:foo/bar.c:42
... msgid "Bar"
... msgstr "\xb5\x7b\xa6\xa1\xbf\xf9\xbb\x7e"
@@ -338,7 +338,7 @@ may include backslashes inside multibyte sequences. These backslashes
must be interpreted as part of the character rather than as an escape
character.
- >>> content = """
+ >>> content = b"""
... msgid ""
... msgstr ""
... "Last-Translator: \xb5\x7b\xa6\xa1\xbf\xf9\xbb\x7e\\n"
@@ -384,7 +384,7 @@ which would cause problems if we naively use '\n' as a line separator.
Change the last PO file to use Mac-style newlines:
- >>> content = content.replace('\n', '\r')
+ >>> content = content.replace(b'\n', b'\r')
Verify that it still parses:
@@ -401,7 +401,7 @@ them have special meaning like 'new line': '\n' or 'tabs' '\t' and others are
just the numeric representation of a character in the declared encoding by
the Content-Type field of the header.
- >>> content = """
+ >>> content = b"""
... msgid ""
... msgstr ""
... "POT-Creation-Date: 2004-05-11 20:22+0800\\n"
@@ -521,7 +521,7 @@ Let's parse a Spanish PO file with an inverted plural formula.
>>> spanish_pluralformula = 'n!=1'
- >>> content = """
+ >>> content = b"""
... msgid ""
... msgstr ""
... "POT-Creation-Date: 2004-05-11 20:22+0800\\n"
diff --git a/lib/lp/translations/utilities/tests/test_gettext_mo_exporter.py b/lib/lp/translations/utilities/tests/test_gettext_mo_exporter.py
index b56970d..6a39c57 100644
--- a/lib/lp/translations/utilities/tests/test_gettext_mo_exporter.py
+++ b/lib/lp/translations/utilities/tests/test_gettext_mo_exporter.py
@@ -33,7 +33,7 @@ class TestGettextMOExporter(TestCaseWithFactory):
msgid "foo"
msgstr "bar"
- """))
+ """).encode("UTF-8"))
file_data.is_template = is_template
file_data.language_code = 'my'
file_data.translation_domain = 'main'
@@ -69,9 +69,9 @@ class TestGettextMOExporter(TestCaseWithFactory):
universal_newlines=False)
self.assertEqual(0, retval)
- self.assertIn('MIME-Version', text)
- self.assertIn('msgid', text)
- self.assertIn('"foo"', text)
+ self.assertIn(b'MIME-Version', text)
+ self.assertIn(b'msgid', text)
+ self.assertIn(b'"foo"', text)
def test_export_template_stays_pot(self):
# The MO exporter exports templates in their original POT
@@ -85,7 +85,7 @@ class TestGettextMOExporter(TestCaseWithFactory):
self.assertEqual('application/x-po', output.content_type)
self.assertTrue(output.path.endswith('.pot'))
text = output.read()
- self.assertIn('POT-Creation-Date:', text)
- self.assertIn('MIME-Version:', text)
- self.assertIn('msgid', text)
- self.assertIn('"foo"', text)
+ self.assertIn(b'POT-Creation-Date:', text)
+ self.assertIn(b'MIME-Version:', text)
+ self.assertIn(b'msgid', text)
+ self.assertIn(b'"foo"', text)
diff --git a/lib/lp/translations/utilities/tests/test_gettext_po_exporter.py b/lib/lp/translations/utilities/tests/test_gettext_po_exporter.py
index 0a9a38a..7bf5479 100644
--- a/lib/lp/translations/utilities/tests/test_gettext_po_exporter.py
+++ b/lib/lp/translations/utilities/tests/test_gettext_po_exporter.py
@@ -1,10 +1,13 @@
# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
+from __future__ import absolute_import, print_function, unicode_literals
+
__metaclass__ = type
from textwrap import dedent
+import six
from zope.interface.verify import verifyObject
from lp.services.helpers import test_diff
@@ -43,12 +46,18 @@ class GettextPOExporterTestCase(TestCaseWithFactory):
:param import_file: buffer with the source file content.
:param export_file: buffer with the output file content.
"""
- import_lines = [line for line in import_file.split('\n')]
+ if import_file == export_file:
+ return
+
+ import_lines = [
+ six.ensure_text(line, errors='replace')
+ for line in import_file.split(b'\n')]
# Remove X-Launchpad-Export-Date line to prevent time bombs in tests.
export_lines = [
- line for line in export_file.split('\n')
- if (not line.startswith('"X-Launchpad-Export-Date:') and
- not line.startswith('"X-Generator: Launchpad'))]
+ six.ensure_text(line, errors='replace')
+ for line in export_file.split(b'\n')
+ if (not line.startswith(b'"X-Launchpad-Export-Date:') and
+ not line.startswith(b'"X-Generator: Launchpad'))]
line_pairs = zip(export_lines, import_lines)
debug_diff = test_diff(import_lines, export_lines)
@@ -124,7 +133,7 @@ class GettextPOExporterTestCase(TestCaseWithFactory):
#~ msgid "zot"
#~ msgstr "zat"
- ''')
+ ''').encode('UTF-8')
cy_translation_file = self.parser.parse(pofile_cy)
cy_translation_file.is_template = False
cy_translation_file.language_code = 'cy'
@@ -159,7 +168,7 @@ class GettextPOExporterTestCase(TestCaseWithFactory):
#| msgid "zog"
msgid "zig"
msgstr "zag"
- ''')
+ ''').encode('UTF-8')
pofile_eo_obsolete = dedent('''
msgid ""
@@ -179,7 +188,7 @@ class GettextPOExporterTestCase(TestCaseWithFactory):
#~| msgid "zog"
#~ msgid "zig"
#~ msgstr "zag"
- ''')
+ ''').encode('UTF-8')
eo_translation_file = self.parser.parse(pofile_eo)
eo_translation_file.is_template = False
eo_translation_file.language_code = 'eo'
@@ -220,64 +229,30 @@ class GettextPOExporterTestCase(TestCaseWithFactory):
self._compareImportAndExport(
pofile.strip(), storage.export().read().strip())
- # File representing the same PO file three times. Each is identical
- # except for the charset declaration in the header.
- pofiles = [
- dedent('''
- msgid ""
- msgstr ""
- "Project-Id-Version: foo\\n"
- "Report-Msgid-Bugs-To: \\n"
- "POT-Creation-Date: 2007-07-09 03:39+0100\\n"
- "PO-Revision-Date: 2001-09-09 01:46+0000\\n"
- "Last-Translator: Kubla Kahn <kk@xxxxxxxxxxxxxxxxx>\\n"
- "Language-Team: LANGUAGE <LL@xxxxxx>\\n"
- "MIME-Version: 1.0\\n"
- "Content-Type: text/plain; charset=UTF-8\\n"
- "Content-Transfer-Encoding: 8bit\\n"
-
- msgid "Japanese"
- msgstr "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"
- '''),
- dedent('''
- msgid ""
- msgstr ""
- "Project-Id-Version: foo\\n"
- "Report-Msgid-Bugs-To: \\n"
- "POT-Creation-Date: 2007-07-09 03:39+0100\\n"
- "PO-Revision-Date: 2001-09-09 01:46+0000\\n"
- "Last-Translator: Kubla Kahn <kk@xxxxxxxxxxxxxxxxx>\\n"
- "Language-Team: LANGUAGE <LL@xxxxxx>\\n"
- "MIME-Version: 1.0\\n"
- "Content-Type: text/plain; charset=Shift-JIS\\n"
- "Content-Transfer-Encoding: 8bit\\n"
-
- msgid "Japanese"
- msgstr "\x93\xfa\x96\x7b\x8c\xea"
- '''),
- dedent('''
- msgid ""
- msgstr ""
- "Project-Id-Version: foo\\n"
- "Report-Msgid-Bugs-To: \\n"
- "POT-Creation-Date: 2007-07-09 03:39+0100\\n"
- "PO-Revision-Date: 2001-09-09 01:46+0000\\n"
- "Last-Translator: Kubla Kahn <kk@xxxxxxxxxxxxxxxxx>\\n"
- "Language-Team: LANGUAGE <LL@xxxxxx>\\n"
- "MIME-Version: 1.0\\n"
- "Content-Type: text/plain; charset=EUC-JP\\n"
- "Content-Transfer-Encoding: 8bit\\n"
-
- msgid "Japanese"
- msgstr "\xc6\xfc\xcb\xdc\xb8\xec"
- '''),
- ]
- for pofile in pofiles:
+ pofile_content = dedent('''
+ msgid ""
+ msgstr ""
+ "Project-Id-Version: foo\\n"
+ "Report-Msgid-Bugs-To: \\n"
+ "POT-Creation-Date: 2007-07-09 03:39+0100\\n"
+ "PO-Revision-Date: 2001-09-09 01:46+0000\\n"
+ "Last-Translator: Kubla Kahn <kk@xxxxxxxxxxxxxxxxx>\\n"
+ "Language-Team: LANGUAGE <LL@xxxxxx>\\n"
+ "MIME-Version: 1.0\\n"
+ "Content-Type: text/plain; charset=%(charset)s\\n"
+ "Content-Transfer-Encoding: 8bit\\n"
+
+ msgid "Japanese"
+ msgstr "\u65e5\u672c\u8a9e"
+ ''')
+ for charset in ('UTF-8', 'Shift-JIS', 'EUC-JP'):
+ pofile = (pofile_content % {'charset': charset}).encode(charset)
compare(self, pofile)
def _testBrokenEncoding(self, pofile_content):
translation_file = self.parser.parse(
- pofile_content % {'charset': 'ISO-8859-15', 'special': '\xe1'})
+ (pofile_content %
+ {'charset': 'ISO-8859-15'}).encode('ISO-8859-15'))
translation_file.is_template = False
translation_file.language_code = 'es'
translation_file.path = 'po/es.po'
@@ -291,8 +266,7 @@ class GettextPOExporterTestCase(TestCaseWithFactory):
translation_file, storage)
self._compareImportAndExport(
- pofile_content.strip() % {
- 'charset': 'UTF-8', 'special': '\xc3\xa1'},
+ (pofile_content.strip() % {'charset': 'UTF-8'}).encode('UTF-8'),
storage.export().read().strip())
def testBrokenEncodingExport(self):
@@ -317,7 +291,7 @@ class GettextPOExporterTestCase(TestCaseWithFactory):
"Content-Transfer-Encoding: 8bit\\n"
msgid "a"
- msgstr "%(special)s"
+ msgstr "\xe1"
''')
self._testBrokenEncoding(pofile_content)
@@ -339,7 +313,7 @@ class GettextPOExporterTestCase(TestCaseWithFactory):
"Report-Msgid-Bugs-To: \\n"
"POT-Creation-Date: 2007-07-09 03:39+0100\\n"
"PO-Revision-Date: 2001-09-09 01:46+0000\\n"
- "Last-Translator: Kubla K%(special)shn <kk@xxxxxxxxxxxxxxxxx>\\n"
+ "Last-Translator: Kubla K\xe1hn <kk@xxxxxxxxxxxxxxxxx>\\n"
"Language-Team: LANGUAGE <LL@xxxxxx>\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=%(charset)s\\n"
@@ -369,9 +343,9 @@ class GettextPOExporterTestCase(TestCaseWithFactory):
msgid "1 dead horse"
msgid_plural "%%d dead horses"
- msgstr[0] "ning\xc3\xban caballo muerto"
+ msgstr[0] "ning\xfan caballo muerto"
%s''')
- translation_file = self.parser.parse(pofile % (''))
+ translation_file = self.parser.parse((pofile % '').encode('UTF-8'))
translation_file.is_template = False
translation_file.language_code = 'es'
translation_file.path = 'po/es.po'
@@ -381,7 +355,8 @@ class GettextPOExporterTestCase(TestCaseWithFactory):
translation_file, storage)
self._compareImportAndExport(
- pofile.strip() % 'msgstr[1] ""', storage.export().read().strip())
+ (pofile.strip() % 'msgstr[1] ""').encode('UTF-8'),
+ storage.export().read().strip())
def testClashingSingularMsgIds(self):
# We don't accept it in gettext imports directly, since it's not
@@ -404,9 +379,9 @@ class GettextPOExporterTestCase(TestCaseWithFactory):
msgid_plural "%d foos"
msgstr[0] ""
msgstr[1] ""
- """).strip()
+ """).strip().encode('UTF-8')
- body = exported_file.split('\n\n', 1)[1].strip()
+ body = exported_file.split(b'\n\n', 1)[1].strip()
self.assertEqual(body, expected_output)
def testObsoleteMessageYieldsToNonObsoleteClashingOne(self):
@@ -442,9 +417,9 @@ class GettextPOExporterTestCase(TestCaseWithFactory):
msgid_plural "%d gooim"
msgstr[0] "%d gargl"
msgstr[1] "%d garglii"
- """).strip()
+ """).strip().encode('UTF-8')
- body = exported_file.split('\n\n', 1)[1].strip()
+ body = exported_file.split(b'\n\n', 1)[1].strip()
self.assertEqual(expected_output, body)
def test_strip_last_newline(self):
@@ -489,5 +464,5 @@ class GettextPOExporterTestCase(TestCaseWithFactory):
# Exporting an empty gettext file does not break the exporter.
# The output does contain one message: the header.
output = self.factory.makePOFile('nl').export()
- self.assertTrue(output.startswith('# Dutch translation for '))
- self.assertEqual(1, output.count('msgid'))
+ self.assertTrue(output.startswith(b'# Dutch translation for '))
+ self.assertEqual(1, output.count(b'msgid'))
diff --git a/lib/lp/translations/utilities/tests/test_gettext_po_parser.py b/lib/lp/translations/utilities/tests/test_gettext_po_parser.py
index 0ea27cd..ad3619e 100644
--- a/lib/lp/translations/utilities/tests/test_gettext_po_parser.py
+++ b/lib/lp/translations/utilities/tests/test_gettext_po_parser.py
@@ -27,15 +27,18 @@ class POBasicTestCase(unittest.TestCase):
def setUp(self):
self.parser = gettext_po_parser.POParser()
+ def parse(self, content_text):
+ return self.parser.parse(content_text.encode('ASCII'))
+
def testEmptyFile(self):
# The parser reports an empty file as an error.
- self.assertRaises(TranslationFormatSyntaxError, self.parser.parse, '')
+ self.assertRaises(TranslationFormatSyntaxError, self.parse, '')
def testEmptyFileError(self):
# Trying to import an empty file produces a sensible error
# message.
try:
- self.parser.parse('')
+ self.parse('')
self.assertTrue(
False,
"Importing an empty file succeeded; it should have failed.")
@@ -48,10 +51,10 @@ class POBasicTestCase(unittest.TestCase):
# The parser reports a non-empty file holding no messages as an
# error.
self.assertRaises(
- TranslationFormatSyntaxError, self.parser.parse, '# Comment')
+ TranslationFormatSyntaxError, self.parse, '# Comment')
def testSingular(self):
- translation_file = self.parser.parse(
+ translation_file = self.parse(
'%smsgid "foo"\nmsgstr "bar"\n' % DEFAULT_HEADER)
messages = translation_file.messages
self.assertEqual(len(messages), 1, "incorrect number of messages")
@@ -63,7 +66,7 @@ class POBasicTestCase(unittest.TestCase):
def testNoNewLine(self):
# note, no trailing newline; this raises a warning
- translation_file = self.parser.parse(
+ translation_file = self.parse(
'%smsgid "foo"\nmsgstr "bar"' % DEFAULT_HEADER)
messages = translation_file.messages
self.assertEqual(messages[0].msgid_singular, "foo", "incorrect msgid")
@@ -73,37 +76,37 @@ class POBasicTestCase(unittest.TestCase):
def testMissingQuote(self):
self.assertRaises(
- TranslationFormatSyntaxError, self.parser.parse,
+ TranslationFormatSyntaxError, self.parse,
'%smsgid "foo"\nmsgstr "bar' % DEFAULT_HEADER)
def testBadNewline(self):
self.assertRaises(
- TranslationFormatSyntaxError, self.parser.parse,
+ TranslationFormatSyntaxError, self.parse,
'%smsgid "foo\n"\nmsgstr "bar"\n' % DEFAULT_HEADER)
def testBadBackslash(self):
self.assertRaises(
- TranslationFormatSyntaxError, self.parser.parse,
+ TranslationFormatSyntaxError, self.parse,
'%smsgid "foo\\"\nmsgstr "bar"\n' % DEFAULT_HEADER)
def testMissingMsgstr(self):
self.assertRaises(
- TranslationFormatSyntaxError, self.parser.parse,
+ TranslationFormatSyntaxError, self.parse,
'%smsgid "foo"\n' % DEFAULT_HEADER)
def testMissingMsgid1(self):
self.assertRaises(
- TranslationFormatSyntaxError, self.parser.parse,
+ TranslationFormatSyntaxError, self.parse,
'%smsgid_plural "foos"\n' % DEFAULT_HEADER)
def testFuzzy(self):
- translation_file = self.parser.parse(
+ translation_file = self.parse(
'%s#, fuzzy\nmsgid "foo"\nmsgstr "bar"\n' % DEFAULT_HEADER)
messages = translation_file.messages
assert 'fuzzy' in messages[0].flags, "missing fuzziness"
def testComment(self):
- translation_file = self.parser.parse('''
+ translation_file = self.parse('''
%s
#. foo/bar.baz\n
# cake not drugs\n
@@ -117,7 +120,7 @@ class POBasicTestCase(unittest.TestCase):
assert 'fuzzy' not in messages[0].flags, "incorrect fuzziness"
def testEscape(self):
- translation_file = self.parser.parse(
+ translation_file = self.parse(
'%smsgid "foo\\"bar\\nbaz\\\\xyzzy"\nmsgstr"z"\n' % (
DEFAULT_HEADER))
messages = translation_file.messages
@@ -127,11 +130,11 @@ class POBasicTestCase(unittest.TestCase):
# def badEscapeTest(self):
#
# self.assertRaises(
- # TranslationFormatSyntaxError, self.parser.parse,
+ # TranslationFormatSyntaxError, self.parse,
# 'msgid "foo\."\nmsgstr "bar"\n')
def testPlural(self):
- translation_file = self.parser.parse('''
+ translation_file = self.parse('''
%s"Plural-Forms: nplurals=2; plural=foo;\\n"
msgid "foo"
@@ -161,7 +164,7 @@ class POBasicTestCase(unittest.TestCase):
msgid_plural "%%d bottles of beer on the wall"
msgstr[zero] = "%%d flessen"''' % DEFAULT_HEADER
self.assertRaises(
- TranslationFormatSyntaxError, self.parser.parse, content)
+ TranslationFormatSyntaxError, self.parse, content)
def testNegativePluralCase(self):
# If a msgid's plural case number is negative, that's a syntax
@@ -173,7 +176,7 @@ class POBasicTestCase(unittest.TestCase):
msgid_plural "%%d ts"
msgstr[-1] "%%d bs"''' % DEFAULT_HEADER
self.assertRaises(
- TranslationFormatSyntaxError, self.parser.parse, content)
+ TranslationFormatSyntaxError, self.parse, content)
def testUnsupportedPluralCase(self):
# If a msgid's plural case number isn't lower than the maximum
@@ -187,10 +190,10 @@ class POBasicTestCase(unittest.TestCase):
msgstr[%d] "%%d bs"''' % (
DEFAULT_HEADER, TranslationConstants.MAX_PLURAL_FORMS)
self.assertRaises(
- TranslationFormatSyntaxError, self.parser.parse, content)
+ TranslationFormatSyntaxError, self.parse, content)
def testObsolete(self):
- translation_file = self.parser.parse(
+ translation_file = self.parse(
'%s#, fuzzy\n#~ msgid "foo"\n#~ msgstr "bar"\n' % DEFAULT_HEADER)
messages = translation_file.messages
self.assertEqual(messages[0].msgid_singular, "foo", "incorrect msgid")
@@ -203,7 +206,7 @@ class POBasicTestCase(unittest.TestCase):
def testObsoleteChangedMsgid(self):
# Test "previous msgid" feature in obsolete messages. These are
# marked with "#~|"
- translation_file = self.parser.parse("""
+ translation_file = self.parse("""
%s
#~| msgid "old"
@@ -216,7 +219,7 @@ class POBasicTestCase(unittest.TestCase):
self.assertEqual(messages[0].translations, ["nouveau"])
def testMultiLineObsolete(self):
- translation_file = self.parser.parse(
+ translation_file = self.parse(
'%s#~ msgid "foo"\n#~ msgstr ""\n#~ "bar"\n' % DEFAULT_HEADER)
messages = translation_file.messages
self.assertEqual(messages[0].msgid_singular, "foo")
@@ -226,7 +229,7 @@ class POBasicTestCase(unittest.TestCase):
def testDuplicateMsgid(self):
self.assertRaises(
- TranslationFormatInvalidInputError, self.parser.parse,
+ TranslationFormatInvalidInputError, self.parse,
'''
%s
msgid "foo"
@@ -238,7 +241,7 @@ class POBasicTestCase(unittest.TestCase):
def testRedundantMsgstr(self):
self.assertRaises(
- TranslationFormatSyntaxError, self.parser.parse,
+ TranslationFormatSyntaxError, self.parse,
'''
%s
msgid "foo"
@@ -248,7 +251,7 @@ class POBasicTestCase(unittest.TestCase):
def testRedundantPlural(self):
self.assertRaises(
- TranslationFormatSyntaxError, self.parser.parse,
+ TranslationFormatSyntaxError, self.parse,
'''
%s
msgid "%%d foo"
@@ -260,7 +263,7 @@ class POBasicTestCase(unittest.TestCase):
def testSquareBracketAndPlural(self):
try:
- self.parser.parse('''
+ self.parse('''
%s
msgid "foo %%d"
msgid_plural "foos %%d"
@@ -274,14 +277,14 @@ class POBasicTestCase(unittest.TestCase):
# DEFAULT_HEADER already contains a msgid and one msgstr
# declaring ASCII encoding. Adding a second msgstr with a
# different text is an error.
- self.assertRaises(TranslationFormatSyntaxError, self.parser.parse,
+ self.assertRaises(TranslationFormatSyntaxError, self.parse,
'''
%s
msgstr "Content-Type: text/plain; charset=UTF-8\\n
''' % DEFAULT_HEADER)
def testUpdateHeader(self):
- translation_file = self.parser.parse(
+ translation_file = self.parse(
'msgid ""\nmsgstr "foo: bar\\n"\n')
translation_file.header.number_plurals = 2
translation_file.header.plural_form_expression = 'random()'
@@ -328,14 +331,14 @@ class POBasicTestCase(unittest.TestCase):
msgid "foo"
msgstr "barf"
""" % DEFAULT_HEADER
- translation_file = self.parser.parse(easy_string)
+ translation_file = self.parse(easy_string)
# If we add an escaped newline, this breaks with a syntax error.
(hard_string, changes) = re.subn("barf", "bar\\\nf", easy_string)
self.assertEqual(changes, 1,
"Failed to add 1 escaped newline to test string.")
- translation_file = self.parser.parse(hard_string)
+ translation_file = self.parse(hard_string)
messages = translation_file.messages
self.assertEqual(len(messages), 1, "Expected exactly 1 message.")
self.assertEqual(
@@ -345,7 +348,7 @@ class POBasicTestCase(unittest.TestCase):
# Test escaped newlines at beginning and end of string, and check for
# interaction with multiple strings on a line.
hard_string = re.sub("barf", "\\\nb" "a\\\nr\\\nf\\\n", easy_string)
- translation_file = self.parser.parse(hard_string)
+ translation_file = self.parse(hard_string)
messages = translation_file.messages
self.assertEqual(
messages[0].translations[TranslationConstants.SINGULAR_FORM],
@@ -354,7 +357,7 @@ class POBasicTestCase(unittest.TestCase):
# After an escaped newline, any indentation on the continued line is
# removed.
hard_string = re.sub("barf", "bar\\\n f", easy_string)
- translation_file = self.parser.parse(hard_string)
+ translation_file = self.parse(hard_string)
messages = translation_file.messages
self.assertEqual(
messages[0].translations[TranslationConstants.SINGULAR_FORM],
@@ -363,7 +366,7 @@ class POBasicTestCase(unittest.TestCase):
# Escaped newlines inside a string do not interfere with the ability
# to continue the string on the next line.
hard_string = re.sub("barf", 'b\\\n"\n"arf', easy_string)
- translation_file = self.parser.parse(hard_string)
+ translation_file = self.parse(hard_string)
messages = translation_file.messages
self.assertEqual(
messages[0].translations[TranslationConstants.SINGULAR_FORM],
@@ -385,7 +388,7 @@ class POBasicTestCase(unittest.TestCase):
break up long strings into multiple lines in the PO file.
"""
foos = 9
- translation_file = self.parser.parse('''
+ translation_file = self.parse('''
%s
msgid "foo1"
msgstr ""
@@ -429,14 +432,14 @@ class POBasicTestCase(unittest.TestCase):
def testGetLastTranslator(self):
"""Tests whether we extract last translator information correctly."""
- template_file = self.parser.parse(DEFAULT_HEADER)
+ template_file = self.parse(DEFAULT_HEADER)
# When it's the default one in Gettext (FULL NAME <EMAIL@ADDRESS>),
# used in templates, we get a tuple with None values.
name, email = template_file.header.getLastTranslator()
self.assertIsNone(name, "Didn't detect default Last Translator name")
self.assertIsNone(email, "Didn't detect default Last Translator email")
- translation_file = self.parser.parse('''
+ translation_file = self.parse('''
msgid ""
msgstr ""
"Last-Translator: Carlos Perello Marin <carlos@xxxxxxxxxxxxx>\\n"