Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed an issue with passing an interpolation mapping in translator.

Previously it was possible to provide an interpolation mapping only as part of
a translation string. Providing it later during translation would be ignored.

This change allows you to provide the mapping as part of the translator call,
e.g.

  translator(tstring, mapping={...})

if the tstring does not contain a mapping itself, the mapping given in the
translator() call will be used as is. Otherwise, the previously given mapping
will be updated with the new values allowing partial overriding of an existing
mapping.
  • Loading branch information...
commit f60864922b6ec2817f409071385b447f71ea30e4 1 parent 463e9c9
@dokai dokai authored
View
26 translationstring/__init__.py
@@ -197,12 +197,12 @@ def translate(msgid, domain=None, mapping=None, context=None,
def ugettext_policy(translations, tstring, domain):
""" A translator policy function which unconditionally uses the
``ugettext`` API on the translations object."""
-
+
if PY3: # pragma: no cover
_gettext = translations.gettext
else: # pragma: no cover
_gettext = translations.ugettext
-
+
return _gettext(tstring)
def dugettext_policy(translations, tstring, domain):
@@ -214,12 +214,12 @@ def dugettext_policy(translations, tstring, domain):
domain = getattr(tstring, 'domain', None) or default_domain
if getattr(translations, 'dugettext', None) is not None:
return translations.dugettext(domain, tstring)
-
+
if PY3: # pragma: no cover
_gettext = translations.gettext
else: # pragma: no cover
_gettext = translations.ugettext
-
+
return _gettext(tstring)
def Translator(translations=None, policy=None):
@@ -233,7 +233,7 @@ def Translator(translations=None, policy=None):
``policy`` should be a callable which accepts three arguments:
``translations``, ``tstring`` and ``domain``. It must perform the
actual translation lookup. If ``policy`` is ``None``, the
- :func:`translationstring.dugettext_policy` policy will be used.
+ :func:`translationstring.dugettext_policy` policy will be used.
The callable returned accepts three arguments: ``tstring``
(required), ``domain`` (optional) and ``mapping`` (optional).
@@ -258,6 +258,10 @@ def translator(tstring, domain=None, mapping=None):
translated = policy(translations, tstring, domain)
if translated == tstring:
translated = tstring.default
+ if tstring.mapping is None:
+ tstring.mapping = mapping
+ elif mapping is not None:
+ tstring.mapping.update(mapping)
if translated and '$' in translated and tstring.mapping:
translated = tstring.interpolate(translated)
return translated
@@ -266,30 +270,30 @@ def translator(tstring, domain=None, mapping=None):
def ungettext_policy(translations, singular, plural, n, domain):
""" A pluralizer policy function which unconditionally uses the
``ungettext`` API on the translations object."""
-
+
if PY3: # pragma: no cover
_gettext = translations.ngettext
else: # pragma: no cover
_gettext = translations.ungettext
-
+
return _gettext(singular, plural, n)
def dungettext_policy(translations, singular, plural, n, domain):
""" A pluralizer policy function which assumes the use of the
:class:`babel.support.Translations` class, which supports the
dungettext API; falls back to ungettext."""
-
+
default_domain = getattr(translations, 'domain', None) or 'messages'
domain = domain or default_domain
-
+
if getattr(translations, 'dungettext', None) is not None:
return translations.dungettext(domain, singular, plural, n)
-
+
if PY3: # pragma: no cover
_gettext = translations.ngettext
else: # pragma: no cover
_gettext = translations.ungettext
-
+
return _gettext(singular, plural, n)
def Pluralizer(translations=None, policy=None):
View
43 translationstring/tests/test_integration.py
@@ -7,7 +7,7 @@ def _makeTranslations(self):
here = os.path.abspath(os.path.dirname(__file__))
localedir = os.path.join(here, 'fixtures', 'locales')
return Translations.load(localedir, locales=['de'])
-
+
def test_translator_ugettext_policy(self):
translations = self._makeTranslations()
from translationstring import Translator
@@ -18,10 +18,10 @@ def test_translator_ugettext_policy(self):
tstring = TranslationString(
'Enter a comma separated list of user names.')
-
+
result = translator(tstring)
self.assertEqual(result, 'Eine kommagetrennte Liste von Benutzernamen.')
-
+
def test_translator_dugettext_policy(self):
translations = self._makeTranslations()
from translationstring import Translator
@@ -32,10 +32,10 @@ def test_translator_dugettext_policy(self):
tstring = TranslationString(
'Enter a comma separated list of user names.')
-
+
result = translator(tstring)
self.assertEqual(result, 'Eine kommagetrennte Liste von Benutzernamen.')
-
+
def test_translator_with_interpolation(self):
translations = self._makeTranslations()
from translationstring import Translator
@@ -45,17 +45,44 @@ def test_translator_with_interpolation(self):
translator = Translator(translations, dugettext_policy)
tstring = TranslationString('Visit ${url}', mapping={'url':'url'})
-
+
result = translator(tstring)
self.assertEqual(result, 'Besuchen url')
-
+
+ def test_translator_with_interpolation_in_translate(self):
+ translations = self._makeTranslations()
+ from translationstring import Translator
+ from translationstring import dugettext_policy
+ from translationstring import TranslationString
+
+ translator = Translator(translations, dugettext_policy)
+
+ tstring = TranslationString('Visit ${url}')
+
+ result = translator(tstring, mapping={'url':'url'})
+ self.assertEqual(result, 'Besuchen url')
+
+ def test_translator_with_interpolation_overridden_in_translate(self):
+ translations = self._makeTranslations()
+ from translationstring import Translator
+ from translationstring import dugettext_policy
+ from translationstring import TranslationString
+
+ translator = Translator(translations, dugettext_policy)
+
+ tstring = TranslationString('Visit ${url}', mapping={'url':'url'})
+
+ result = translator(tstring, mapping={'url':'new_url'})
+ self.assertEqual(result, 'Besuchen new_url')
+
+
class PluralizerIntegrationTests(unittest.TestCase):
def _makeTranslations(self):
import os
here = os.path.abspath(os.path.dirname(__file__))
localedir = os.path.join(here, 'fixtures', 'locales')
return Translations.load(localedir, locales=['de'])
-
+
def test_pluralizer_ungettext_policy(self):
translations = self._makeTranslations()
from translationstring import Pluralizer
Please sign in to comment.
Something went wrong with that request. Please try again.