diff --git a/lower-constraints.txt b/lower-constraints.txt index 9fadd9e..b3bca92 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -1,6 +1,5 @@ alabaster==0.7.10 appdirs==1.3.0 -Babel==2.3.4 bandit==1.4.0 coverage==4.0 debtcollector==1.2.0 diff --git a/oslo_i18n/_gettextutils.py b/oslo_i18n/_gettextutils.py index 00028a6..bc6946f 100644 --- a/oslo_i18n/_gettextutils.py +++ b/oslo_i18n/_gettextutils.py @@ -19,10 +19,9 @@ import copy import gettext +import locale import os -from babel import localedata - from oslo_i18n import _factory from oslo_i18n import _locale @@ -62,43 +61,20 @@ def get_available_languages(domain): return copy.copy(_AVAILABLE_LANGUAGES[domain]) localedir = os.environ.get(_locale.get_locale_dir_variable_name(domain)) - find = lambda x: gettext.find(domain, - localedir=localedir, - languages=[x]) + + def find(x): + return gettext.find(domain, localedir=localedir, languages=[x]) # NOTE(mrodden): en_US should always be available (and first in case # order matters) since our in-line message strings are en_US language_list = ['en_US'] - locale_identifiers = localedata.locale_identifiers() - language_list.extend(language for language in locale_identifiers - if find(language)) + locale_identifiers = set(locale.windows_locale.values()) + language_list.extend( + language for language in locale_identifiers if find(language) + ) - # In Babel 1.3, locale_identifiers() doesn't list some OpenStack supported - # locales (e.g. 'zh_CN', and 'zh_TW') so we add the locales explicitly if - # necessary so that they are listed as supported. - aliases = {'zh': 'zh_CN', - 'zh_Hant_HK': 'zh_HK', - 'zh_Hant': 'zh_TW', - 'fil': 'tl_PH'} - language_list.extend(alias for locale, alias in aliases.items() - if (locale in language_list and - alias not in language_list)) - - language_list.extend(alias for locale, alias in aliases.items() - if (locale not in language_list and - find(alias))) - - # In webob.acceptparse, the best_match is just match the first element in - # the language_list, so make the precise element in front - result = ['en_US'] - for i in language_list[1:]: - if '_' in i: - result.insert(1, i) - else: - result.append(i) - - _AVAILABLE_LANGUAGES[domain] = result - return copy.copy(result) + _AVAILABLE_LANGUAGES[domain] = language_list + return copy.copy(language_list) _original_find = gettext.find diff --git a/oslo_i18n/tests/test_gettextutils.py b/oslo_i18n/tests/test_gettextutils.py index 0592542..49f95e1 100644 --- a/oslo_i18n/tests/test_gettextutils.py +++ b/oslo_i18n/tests/test_gettextutils.py @@ -18,7 +18,6 @@ import gettext import logging from unittest import mock -from babel import localedata from oslotest import base as test_base import six @@ -75,29 +74,15 @@ class GettextTest(test_base.BaseTestCase): self.assertIn('_', six.moves.builtins.__dict__) def test_get_available_languages(self): - # All the available languages for which locale data is available - def _mock_locale_identifiers(): - # 'zh', 'zh_Hant'. 'zh_Hant_HK', 'fil' all have aliases - # missing from babel but we add them in _gettextutils, we - # test that here too - return ['zh', 'es', 'nl', 'fr', 'zh_Hant', 'zh_Hant_HK', 'fil'] - - mock_patcher = mock.patch.object(localedata, - 'list' if hasattr(localedata, 'list') - else 'locale_identifiers', - _mock_locale_identifiers) - mock_patcher.start() - self.addCleanup(mock_patcher.stop) - # Only the languages available for a specific translation domain def _mock_gettext_find(domain, localedir=None, languages=None, all=0): languages = languages or [] if domain == 'domain_1': - return 'translation-file' if any(x in ['zh', 'es', 'fil'] - for x in languages) else None + if any(x in ['en_GB', 'es_ES', 'fil_PH'] for x in languages): + return 'translation-file' elif domain == 'domain_2': - return 'translation-file' if any(x in ['fr', 'zh_Hant'] - for x in languages) else None + if any(x in ['fr_FR', 'zh_HK'] for x in languages): + return 'translation-file' return None mock_patcher = mock.patch.object(gettext, 'find', _mock_gettext_find) mock_patcher.start() @@ -110,20 +95,19 @@ class GettextTest(test_base.BaseTestCase): # and it should also always be the first element since order matters domain_1_languages = _gettextutils.get_available_languages('domain_1') domain_2_languages = _gettextutils.get_available_languages('domain_2') - self.assertEqual('en_US', domain_1_languages[0]) - self.assertEqual('en_US', domain_2_languages[0]) + # The domain languages should be included after en_US with # with their respective aliases when it applies - self.assertEqual(6, len(domain_1_languages)) - self.assertIn('zh', domain_1_languages) - self.assertIn('zh_CN', domain_1_languages) - self.assertIn('es', domain_1_languages) - self.assertIn('fil', domain_1_languages) - self.assertIn('tl_PH', domain_1_languages) - self.assertEqual(4, len(domain_2_languages)) - self.assertIn('fr', domain_2_languages) - self.assertIn('zh_Hant', domain_2_languages) - self.assertIn('zh_TW', domain_2_languages) + self.assertEqual('en_US', domain_1_languages[0]) + self.assertEqual('en_US', domain_2_languages[0]) + + self.assertEqual(4, len(domain_1_languages), domain_1_languages) + self.assertEqual( + {'en_US', 'fil_PH', 'en_GB', 'es_ES'}, set(domain_1_languages), + ) + self.assertEqual(3, len(domain_2_languages), domain_2_languages) + self.assertEqual({'en_US', 'fr_FR', 'zh_HK'}, set(domain_2_languages)) + self.assertEqual(2, len(_gettextutils._AVAILABLE_LANGUAGES)) # Now test an unknown domain, only en_US should be included unknown_domain_languages = _gettextutils.get_available_languages('huh') diff --git a/requirements.txt b/requirements.txt index bad16ca..a072ac0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,5 +3,4 @@ # process, which may cause wedges in the gate later. pbr!=2.1.0,>=2.0.0 # Apache-2.0 -Babel!=2.4.0,>=2.3.4 # BSD six>=1.10.0 # MIT