Changeset 15121 in trac.svn


Ignore:
Timestamp:
Sep 6, 2016, 6:23:47 AM (7 years ago)
Author:
jomae
Message:

1.2dev: merge [15119-15120] from 1.0-stable (fix for #12418)

Location:
branches/1.2-stable
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • branches/1.2-stable

  • branches/1.2-stable/trac/admin/api.py

    r12785 r15121  
    198198
    199199
    200 def get_console_locale(env=None, lang=LANG):
    201     """Return negotiated locale for console by LANG environment and
     200def get_console_locale(env=None, lang=None,
     201                       categories=('LANGUAGE', 'LC_ALL', 'LC_MESSAGES',
     202                                   'LANG')):
     203    """Return negotiated locale for console by locale environments and
    202204    [trac] default_language."""
    203205    if has_babel:
    204206        from babel.core import Locale, UnknownLocaleError, parse_locale
     207        def normalize(value):
     208            if not value:
     209                return None
     210            try:
     211                return '_'.join(filter(None, parse_locale(value)))
     212            except:
     213                return None
     214        locales = [lang]
     215        for category in categories:
     216            value = os.environ.get(category)
     217            if not value:
     218                continue
     219            if category == 'LANGUAGE' and ':' in value:
     220                value = value.split(':')[0]
     221            locales.append(value)
     222        if env:
     223            locales.append(env.config.get('trac', 'default_language'))
     224        locales = filter(None, map(normalize, locales))
    205225        try:
    206             lang = '_'.join(filter(None, parse_locale(lang)))
    207         except:
    208             lang = None
    209         default = env.config.get('trac', 'default_language', '') \
    210                   if env else None
    211         try:
    212             return get_negotiated_locale([lang, default]) or Locale.default()
     226            return get_negotiated_locale(locales)
    213227        except UnknownLocaleError:
    214228            pass
  • branches/1.2-stable/trac/admin/tests/console.py

    r14861 r15121  
    187187        self._admin = TracAdmin()
    188188        self._admin.env_set('', self.env)
     189        self.environ = os.environ.copy()
    189190
    190191        # Set test date to 11th Jan 2004
     
    193194    def tearDown(self):
    194195        self.env = None
     196        for name in set(os.environ) - set(self.environ):
     197            del os.environ[name]
     198        os.environ.update(self.environ)
    195199
    196200    @property
     
    244248        en_US = Locale.parse('en_US')
    245249        de = Locale.parse('de')
    246         de_DE = Locale.parse('de_DE')
    247         try:
    248             default = Locale.default()
    249         except UnknownLocaleError:
    250             default = None
    251 
    252         language = self.env.config.get('trac', 'default_language')
    253         try:
    254             self.assertEqual(default, get_console_locale(None, None))
    255             self.env.config.set('trac', 'default_language', '')
    256             if 'de' in locales:
    257                 self.assertEqual(de, get_console_locale(None, 'de_DE.UTF8'))
    258                 self.env.config.set('trac', 'default_language', 'de')
    259                 self.assertEqual(de, get_console_locale(self.env, None))
    260                 self.assertEqual(de, get_console_locale(self.env, 'C'))
    261                 self.env.config.set('trac', 'default_language', 'en_US')
    262                 self.assertEqual(en_US, get_console_locale(self.env, None))
    263                 self.assertEqual(en_US, get_console_locale(self.env, 'C'))
    264                 self.assertEqual(de, get_console_locale(self.env,
    265                                                         'de_DE.UTF8'))
    266             if not locales:  # compiled catalog is missing
    267                 self.assertEqual(default, get_console_locale(None,
    268                                                              'de_DE.UTF8'))
    269                 self.env.config.set('trac', 'default_language', 'de')
    270                 self.assertEqual(default, get_console_locale(self.env, None))
    271                 self.assertEqual(default, get_console_locale(self.env, 'C'))
    272                 self.env.config.set('trac', 'default_language', 'en_US')
    273                 self.assertEqual(en_US, get_console_locale(self.env, None))
    274                 self.assertEqual(en_US, get_console_locale(self.env, 'C'))
    275                 self.assertEqual(en_US, get_console_locale(self.env,
    276                                                            'de_DE.UTF8'))
    277         finally:
    278             self.env.config.set('trac', 'default_language', language)
     250
     251        def unset_locale_envs():
     252            for name in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
     253                if name in os.environ:
     254                    del os.environ[name]
     255
     256        if 'de' in locales:
     257            unset_locale_envs()
     258            self.assertEqual(None, get_console_locale(None, None))
     259            self.assertEqual(de, get_console_locale(None, 'de_DE.UTF8'))
     260            self.env.config.set('trac', 'default_language', 'de')
     261            self.assertEqual(de, get_console_locale(self.env, None))
     262            self.assertEqual(de, get_console_locale(self.env, 'C'))
     263            self.env.config.set('trac', 'default_language', 'en_US')
     264            self.assertEqual(en_US, get_console_locale(self.env, None))
     265            self.assertEqual(en_US, get_console_locale(self.env, 'C'))
     266            self.assertEqual(de, get_console_locale(self.env,
     267                                                    'de_DE.UTF8'))
     268
     269            self.env.config.set('trac', 'default_language', 'de')
     270            os.environ['LANG'] = 'POSIX'  # unavailable locale in Trac
     271            self.assertEqual(None, get_console_locale())
     272            self.assertEqual(de, get_console_locale(self.env))
     273            os.environ['LANG'] = '****'  # invalid locale
     274            self.assertEqual(None, get_console_locale())
     275            self.assertEqual(de, get_console_locale(self.env))
     276            os.environ['LANG'] = 'en_US.utf-8'
     277            self.assertEqual(en_US, get_console_locale())
     278            self.assertEqual(en_US, get_console_locale(self.env))
     279            os.environ['LC_MESSAGES'] = 'de_DE.utf-8'
     280            self.assertEqual(de, get_console_locale())
     281            self.assertEqual(de, get_console_locale(self.env))
     282            os.environ['LC_ALL'] = 'en_US.utf-8'
     283            self.assertEqual(en_US, get_console_locale())
     284            self.assertEqual(en_US, get_console_locale(self.env))
     285            os.environ['LANGUAGE'] = 'de_DE:en_US:en'
     286            self.assertEqual(de, get_console_locale())
     287            self.assertEqual(de, get_console_locale(self.env))
     288
     289        if not locales:  # compiled catalog is missing
     290            unset_locale_envs()
     291            self.assertEqual(None, get_console_locale(None, 'de_DE.UTF8'))
     292            self.env.config.set('trac', 'default_language', 'de')
     293            self.assertEqual(None, get_console_locale(self.env, None))
     294            self.assertEqual(None, get_console_locale(self.env, 'C'))
     295            self.assertEqual(None, get_console_locale(self.env,
     296                                                      'de_DE.UTF8'))
     297            os.environ['LANG'] = 'en_US.utf-8'
     298            os.environ['LC_MESSAGES'] = 'de_DE.utf-8'
     299            os.environ['LC_ALL'] = 'en_US.utf-8'
     300            os.environ['LANGUAGE'] = 'de_DE:en_US'
     301            self.assertEqual(en_US, get_console_locale())
     302            self.assertEqual(en_US, get_console_locale(self.env))
    279303
    280304    def _test_get_console_locale_without_babel(self):
     305        os.environ['LANG'] = 'en_US.utf-8'
     306        os.environ['LC_MESSAGES'] = 'de_DE.utf-8'
     307        os.environ['LC_ALL'] = 'en_US.utf-8'
     308        os.environ['LANGUAGE'] = 'de_DE:en_US'
    281309        self.assertEqual(None, get_console_locale(None, 'en_US.UTF8'))
    282         language = self.env.config.get('trac', 'default_language')
    283         try:
    284             self.env.config.set('trac', 'default_language', 'en_US')
    285             self.assertEqual(None, get_console_locale(self.env, 'en_US.UTF8'))
    286         finally:
    287             self.env.config.set('trac', 'default_language', language)
     310        self.env.config.set('trac', 'default_language', '')
     311        self.assertEqual(None, get_console_locale(self.env, 'en_US.UTF8'))
     312        self.assertEqual(None, get_console_locale(self.env))
     313        self.env.config.set('trac', 'default_language', 'en_US')
     314        self.assertEqual(None, get_console_locale(self.env, 'en_US.UTF8'))
     315        self.assertEqual(None, get_console_locale(self.env))
    288316
    289317    if has_babel:
  • branches/1.2-stable/trac/util/tests/text.py

    r14779 r15121  
    1818
    1919import trac.tests.compat
    20 from trac.util.text import empty, expandtabs, fix_eol, javascript_quote, \
    21                            levenshtein_distance, normalize_whitespace, \
    22                            print_table, quote_query_string, shorten_line, \
    23                            strip_line_ws, stripws, sub_vars, text_width, \
    24                            to_js_string, to_unicode, to_utf8, \
    25                            unicode_from_base64, unicode_quote, \
    26                            unicode_quote_plus, unicode_to_base64, \
    27                            unicode_unquote, unicode_urlencode, wrap
     20from trac.util.text import (
     21    _get_default_ambiwidth, empty, expandtabs, fix_eol, javascript_quote,
     22    levenshtein_distance, normalize_whitespace, print_table,
     23    quote_query_string, shorten_line, strip_line_ws, stripws, sub_vars,
     24    text_width, to_js_string, to_unicode, to_utf8, unicode_from_base64,
     25    unicode_quote, unicode_quote_plus, unicode_to_base64, unicode_unquote,
     26    unicode_urlencode, wrap)
    2827
    2928
     
    428427
    429428
     429class DefaultAmbiwidthTestCase(unittest.TestCase):
     430
     431    def setUp(self):
     432        self.environ = os.environ.copy()
     433
     434    def tearDown(self):
     435        for name in set(os.environ) - set(self.environ):
     436            del os.environ[name]
     437        os.environ.update(self.environ)
     438
     439    def _unset_locale_envs(self):
     440        for name in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
     441            if name in os.environ:
     442                del os.environ[name]
     443
     444    def _test_ambiwidth(self, expected, envs):
     445        self._unset_locale_envs()
     446        os.environ.update(envs)
     447        self.assertEqual(expected, _get_default_ambiwidth())
     448
     449    def test_no_locale_envs(self):
     450        self._unset_locale_envs()
     451        self.assertEqual(1, _get_default_ambiwidth())
     452
     453    def test_language(self):
     454        self._test_ambiwidth(1, {'LANGUAGE': 'C'})
     455        self._test_ambiwidth(1, {'LANGUAGE': 'POSIX'})
     456        self._test_ambiwidth(1, {'LANGUAGE': 'de_DE'})
     457        self._test_ambiwidth(2, {'LANGUAGE': 'ko'})
     458        self._test_ambiwidth(2, {'LANGUAGE': 'ko_KR'})
     459        self._test_ambiwidth(2, {'LANGUAGE': 'ja'})
     460        self._test_ambiwidth(2, {'LANGUAGE': 'ja_JP'})
     461        self._test_ambiwidth(2, {'LANGUAGE': 'zh_CN'})
     462        self._test_ambiwidth(2, {'LANGUAGE': 'zh_TW'})
     463        self._test_ambiwidth(1, {'LANGUAGE': 'en_US:ja:zh_TW'})
     464        self._test_ambiwidth(2, {'LANGUAGE': 'zh_CN:en:ko'})
     465        self._test_ambiwidth(1, {'LANGUAGE': '*****'})
     466
     467    def test_simple_locale_env(self):
     468        for name in ('LC_ALL', 'LC_MESSAGES', 'LANG'):
     469            self._test_ambiwidth(1, {name: 'C'})
     470            self._test_ambiwidth(1, {name: 'POSIX'})
     471            self._test_ambiwidth(1, {name: 'en_US.UTF8'})
     472            self._test_ambiwidth(1, {name: 'de_DE.UTF8'})
     473            self._test_ambiwidth(2, {name: 'ko_KR.UTF8'})
     474            self._test_ambiwidth(2, {name: 'ja_JP.UTF8'})
     475            self._test_ambiwidth(2, {name: 'zh_CN.UTF8'})
     476            self._test_ambiwidth(2, {name: 'zh_TW.UTF8'})
     477            self._test_ambiwidth(1, {name: '*****'})
     478
     479    def test_combined_locale_envs(self):
     480        os.environ.update({'LANGUAGE': 'en_US',
     481                           'LC_ALL': 'zh_TW.UTF8', 'LC_MESSAGES': 'de_DE.UTF8',
     482                           'LANG': 'ko_KR.UTF8'})
     483        self.assertEqual(1, _get_default_ambiwidth())
     484        del os.environ['LANGUAGE']
     485        self.assertEqual(2, _get_default_ambiwidth())
     486        del os.environ['LC_ALL']
     487        self.assertEqual(1, _get_default_ambiwidth())
     488        del os.environ['LC_MESSAGES']
     489        self.assertEqual(2, _get_default_ambiwidth())
     490        del os.environ['LANG']
     491        self.assertEqual(1, _get_default_ambiwidth())
     492
     493
    430494def test_suite():
    431495    suite = unittest.TestSuite()
     
    447511    suite.addTest(unittest.makeSuite(SubVarsTestCase))
    448512    suite.addTest(unittest.makeSuite(ShortenLineTestCase))
     513    if os.name != 'nt':
     514        suite.addTest(unittest.makeSuite(DefaultAmbiwidthTestCase))
    449515    return suite
     516
    450517
    451518if __name__ == '__main__':
  • branches/1.2-stable/trac/util/text.py

    r14258 r15121  
    326326                for chr in to_unicode(text)])
    327327
    328 _default_ambiwidth = 1  # Default width of East Asian Ambiguous (A)
    329 if os.name == 'nt':
    330     import ctypes
    331     codepage = ctypes.windll.kernel32.GetConsoleOutputCP()
    332 
    333     if codepage in (932,  # Japanese (Shift-JIS)
    334                     936,  # Chinese Simplified (GB2312)
    335                     949,  # Korean (Unified Hangul Code)
    336                     950): # Chinese Traditional (Big5)
    337         _default_ambiwidth = 2
    338     del codepage
    339 else:
    340     if re.match(r'zh|ja|kr', os.environ.get('LANG') or '', re.IGNORECASE):
    341         _default_ambiwidth = 2
     328
     329def _get_default_ambiwidth():
     330    """Return width of East Asian Ambiguous based on locale environment
     331    variables or Windows codepage.
     332    """
     333
     334    if os.name == 'nt':
     335        import ctypes
     336        codepage = ctypes.windll.kernel32.GetConsoleOutputCP()
     337        if codepage in (932,   # Japanese (Shift-JIS)
     338                        936,   # Chinese Simplified (GB2312)
     339                        949,   # Korean (Unified Hangul Code)
     340                        950):  # Chinese Traditional (Big5)
     341            return 2
     342    else:
     343        for name in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
     344            value = os.environ.get(name) or ''
     345            if value:
     346                if name == 'LANGUAGE' and ':' in value:
     347                    value = value.split(':')[0]
     348                return 2 if value.lower().startswith(('zh', 'ja', 'ko')) else 1
     349
     350    return 1
     351
     352
     353_default_ambiwidth = _get_default_ambiwidth()
    342354
    343355
Note: See TracChangeset for help on using the changeset viewer.