Rev 5932: (vila) Introduce bzrlib.i18n (INADA Naoki) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Fri May 27 23:57:34 UTC 2011


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 5932 [merge]
revision-id: pqm at pqm.ubuntu.com-20110527235731-gz1bly4xdi5y3zur
parent: pqm at pqm.ubuntu.com-20110527223837-54h5nrj2y10wgj8o
parent: v.ladeuil+lp at free.fr-20110527214102-1vk9kyq1pdfm08kr
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Fri 2011-05-27 23:57:31 +0000
message:
  (vila) Introduce bzrlib.i18n (INADA Naoki)
added:
  bzrlib/i18n.py                 i18n.py-20110429130428-eblvodng604h3dzi-1
  bzrlib/tests/test_i18n.py      test_i18n.py-20110517012016-wjj0ai7qrasnj49p-1
modified:
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
=== added file 'bzrlib/i18n.py'
--- a/bzrlib/i18n.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/i18n.py	2011-05-27 21:38:33 +0000
@@ -0,0 +1,135 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2007 Lukáš Lalinský <lalinsky at gmail.com>
+# Copyright (C) 2007,2009 Alexander Belchenko <bialix at ukr.net>
+# Copyright (C) 2011 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# This module is copied from Bazaar Explorer and modified for bzr.
+
+"""i18n and l10n support for Bazaar."""
+
+import gettext as _gettext
+import os
+import sys
+
+_translation = _gettext.NullTranslations()
+
+
+def gettext(message):
+    """Translate message. 
+    
+    :returns: translated message as unicode.
+    """
+    return _translation.ugettext(message)
+
+
+def ngettext(s, p, n):
+    """Translate message based on `n`.
+
+    :returns: translated message as unicode.
+    """
+    return _translation.ungettext(s, p, n)
+
+
+def N_(msg):
+    """Mark message for translation but don't translate it right away."""
+    return msg
+
+
+def gettext_per_paragraph(message):
+    """Translate message per paragraph.
+
+    :returns: concatenated translated message as unicode.
+    """
+    paragraphs = message.split(u'\n\n')
+    ugettext = _translation.ugettext
+    # Be careful not to translate the empty string -- it holds the
+    # meta data of the .po file.
+    return u'\n\n'.join(ugettext(p) if p else u'' for p in paragraphs)
+
+
+def install(lang=None):
+    global _translation
+    if lang is None:
+        lang = _get_current_locale()
+    _translation = _gettext.translation(
+            'bzr',
+            localedir=_get_locale_dir(),
+            languages=lang.split(':'),
+            fallback=True)
+
+
+def uninstall():
+    global _translation
+    _translation = _null_translation
+
+
+def _get_locale_dir():
+    if hasattr(sys, 'frozen'):
+        base = os.path.dirname(
+                unicode(sys.executable, sys.getfilesystemencoding()))
+        return os.path.join(base, u'locale')
+    else:
+        base = os.path.dirname(unicode(__file__, sys.getfilesystemencoding()))
+        dirpath = os.path.realpath(os.path.join(base, u'locale'))
+        if os.path.exists(dirpath):
+            return dirpath
+        else:
+            return '/usr/share/locale'
+
+
+def _check_win32_locale():
+    for i in ('LANGUAGE','LC_ALL','LC_MESSAGES','LANG'):
+        if os.environ.get(i):
+            break
+    else:
+        lang = None
+        import locale
+        try:
+            import ctypes
+        except ImportError:
+            # use only user's default locale
+            lang = locale.getdefaultlocale()[0]
+        else:
+            # using ctypes to determine all locales
+            lcid_user = ctypes.windll.kernel32.GetUserDefaultLCID()
+            lcid_system = ctypes.windll.kernel32.GetSystemDefaultLCID()
+            if lcid_user != lcid_system:
+                lcid = [lcid_user, lcid_system]
+            else:
+                lcid = [lcid_user]
+            lang = [locale.windows_locale.get(i) for i in lcid]
+            lang = ':'.join([i for i in lang if i])
+        # set lang code for gettext
+        if lang:
+            os.environ['LANGUAGE'] = lang
+
+
+def _get_current_locale():
+    if not os.environ.get('LANGUAGE'):
+        from bzrlib import config
+        lang = config.GlobalConfig().get_user_option('language')
+        if lang:
+            os.environ['LANGUAGE'] = lang
+            return lang
+    if sys.platform == 'win32':
+        _check_win32_locale()
+    for i in ('LANGUAGE','LC_ALL','LC_MESSAGES','LANG'):
+        lang = os.environ.get(i)
+        if lang:
+            return lang
+    return None

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2011-05-27 02:22:45 +0000
+++ b/bzrlib/tests/__init__.py	2011-05-27 21:41:02 +0000
@@ -3808,6 +3808,7 @@
         'bzrlib.tests.test_http',
         'bzrlib.tests.test_http_response',
         'bzrlib.tests.test_https_ca_bundle',
+        'bzrlib.tests.test_i18n',
         'bzrlib.tests.test_identitymap',
         'bzrlib.tests.test_ignores',
         'bzrlib.tests.test_index',

=== added file 'bzrlib/tests/test_i18n.py'
--- a/bzrlib/tests/test_i18n.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/test_i18n.py	2011-05-27 06:37:07 +0000
@@ -0,0 +1,93 @@
+# Copyright (C) 2011 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Tests for bzrlib.i18n"""
+
+from bzrlib import i18n, tests
+
+
+
+
+class ZzzTranslations(object):
+    """Special Zzz translation for debugging i18n stuff.
+
+    This class can be used to confirm that the message is properly translated
+    during black box tests.
+    """
+    _null_translation = i18n._gettext.NullTranslations()
+
+    def zzz(self, s):
+        return u'zz{{%s}}' % s
+
+    def ugettext(self, s):
+        return self.zzz(self._null_translation.ugettext(s))
+
+    def ungettext(self, s, p, n):
+        return self.zzz(self._null_translation.ungettext(s, p, n))
+
+
+class TestZzzTranslation(tests.TestCase):
+
+    def _check_exact(self, expected, source):
+        self.assertEqual(expected, source)
+        self.assertEqual(type(expected), type(source))
+
+    def test_translation(self):
+        trans = ZzzTranslations()
+
+        t = trans.zzz('msg')
+        self._check_exact(u'zz{{msg}}', t)
+
+        t = trans.ugettext('msg')
+        self._check_exact(u'zz{{msg}}', t)
+
+        t = trans.ungettext('msg1', 'msg2', 0)
+        self._check_exact(u'zz{{msg2}}', t)
+        t = trans.ungettext('msg1', 'msg2', 2)
+        self._check_exact(u'zz{{msg2}}', t)
+
+        t = trans.ungettext('msg1', 'msg2', 1)
+        self._check_exact(u'zz{{msg1}}', t)
+
+
+class TestGetText(tests.TestCase):
+
+    def setUp(self):
+        super(TestGetText, self).setUp()
+        self.overrideAttr(i18n, '_translation', ZzzTranslations())
+
+    def test_oneline(self):
+        self.assertEqual(u"zz{{spam ham eggs}}",
+                         i18n.gettext("spam ham eggs"))
+
+    def test_multiline(self):
+        self.assertEqual(u"zz{{spam\nham\n\neggs\n}}",
+                         i18n.gettext("spam\nham\n\neggs\n"))
+
+
+class TestGetTextPerParagraph(tests.TestCase):
+
+    def setUp(self):
+        super(TestGetTextPerParagraph, self).setUp()
+        self.overrideAttr(i18n, '_translation', ZzzTranslations())
+
+    def test_oneline(self):
+        self.assertEqual(u"zz{{spam ham eggs}}",
+                         i18n.gettext_per_paragraph("spam ham eggs"))
+
+    def test_multiline(self):
+        self.assertEqual(u"zz{{spam\nham}}\n\nzz{{eggs\n}}",
+                         i18n.gettext_per_paragraph("spam\nham\n\neggs\n"))




More information about the bazaar-commits mailing list