Fixed #14894 -- Ensure that activating a translation doesn't run into threading issues.

Thanks to maxbublis for the report and sergeykolosov for the patch.
This commit is contained in:
Florian Apolloner 2013-05-18 17:36:31 +02:00
parent 710c59bf9b
commit acd0bb39df
2 changed files with 31 additions and 1 deletions

View File

@ -140,7 +140,7 @@ def translation(language):
# doesn't affect en-gb), even though they will both use the core "en"
# translation. So we have to subvert Python's internal gettext caching.
base_lang = lambda x: x.split('-', 1)[0]
if base_lang(lang) in [base_lang(trans) for trans in _translations]:
if base_lang(lang) in [base_lang(trans) for trans in list(_translations)]:
res._info = res._info.copy()
res._catalog = res._catalog.copy()

View File

@ -334,6 +334,36 @@ class TranslationTests(TestCase):
self.assertEqual(rendered, 'My other name is James.')
class TranslationThreadSafetyTests(TestCase):
def setUp(self):
self._old_language = get_language()
self._translations = trans_real._translations
# here we rely on .split() being called inside the _fetch()
# in trans_real.translation()
class sideeffect_str(str):
def split(self, *args, **kwargs):
res = str.split(self, *args, **kwargs)
trans_real._translations['en-YY'] = None
return res
trans_real._translations = {sideeffect_str('en-XX'): None}
def tearDown(self):
trans_real._translations = self._translations
activate(self._old_language)
def test_bug14894_translation_activate_thread_safety(self):
translation_count = len(trans_real._translations)
try:
translation.activate('pl')
except RuntimeError:
self.fail('translation.activate() is not thread-safe')
# make sure sideeffect_str actually added a new translation
self.assertLess(translation_count, len(trans_real._translations))
@override_settings(USE_L10N=True)
class FormattingTests(TestCase):