Ticket #14894: bug-14894-translation-thread-safety.diff

File bug-14894-translation-thread-safety.diff, 2.1 KB (added by sergeykolosov, 2 years ago)

Patch which uses list() on _translations, so that it is Python 3.x complatible (where .keys() is an iterator); along with a regression test.

  • django/utils/translation/trans_real.py

    diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py
    index 07353c3..8c54862 100644
    a b def translation(language): 
    140140        # doesn't affect en-gb), even though they will both use the core "en"
    141141        # translation. So we have to subvert Python's internal gettext caching.
    142142        base_lang = lambda x: x.split('-', 1)[0]
    143         if base_lang(lang) in [base_lang(trans) for trans in _translations]:
     143        if base_lang(lang) in [base_lang(trans) for trans in list(_translations)]:
    144144            res._info = res._info.copy()
    145145            res._catalog = res._catalog.copy()
    146146
  • tests/i18n/tests.py

    diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py
    index 1022c8d..0726bcf 100644
    a b class TranslationTests(TestCase): 
    333333            self.assertEqual(rendered, 'My other name is James.')
    334334
    335335
     336class TranslationThreadSafetyTests(TestCase):
     337    def setUp(self):
     338        self._old_language = get_language()
     339        self._translations = trans_real._translations
     340
     341        # here we rely on .split() being called inside 'base_lang' lambda
     342        # in _fetch() in trans_real.translation()
     343        class sideeffect_str(str):
     344            def split(self, *args, **kwargs):
     345                res = str.split(self, *args, **kwargs)
     346                trans_real._translations['en-YY'] = None
     347                return res
     348
     349        trans_real._translations = {sideeffect_str('en-XX'): None}
     350
     351    def tearDown(self):
     352        trans_real._translations = self._translations
     353        activate(self._old_language)
     354
     355    def test_bug14894_translation_activate_thread_safety(self):
     356        translation_count = len(trans_real._translations)
     357        try:
     358            translation.activate('pl')
     359        except RuntimeError:
     360            self.fail('translation.activate() is not thread-safe')
     361
     362        # make sure sideeffect_str actually added a new translation
     363        self.assertLess(translation_count, len(trans_real._translations))
     364
     365
    336366@override_settings(USE_L10N=True)
    337367class FormattingTests(TestCase):
    338368
Back to Top