(root)/
Python-3.12.0/
Lib/
test/
test_locale.py
       1  from decimal import Decimal
       2  from test.support import verbose, is_android, is_emscripten, is_wasi
       3  from test.support.warnings_helper import check_warnings
       4  import unittest
       5  import locale
       6  import sys
       7  import codecs
       8  
       9  
      10  class ESC[4;38;5;81mBaseLocalizedTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      11      #
      12      # Base class for tests using a real locale
      13      #
      14  
      15      @classmethod
      16      def setUpClass(cls):
      17          if sys.platform == 'darwin':
      18              import os
      19              tlocs = ("en_US.UTF-8", "en_US.ISO8859-1", "en_US")
      20              if int(os.uname().release.split('.')[0]) < 10:
      21                  # The locale test work fine on OSX 10.6, I (ronaldoussoren)
      22                  # haven't had time yet to verify if tests work on OSX 10.5
      23                  # (10.4 is known to be bad)
      24                  raise unittest.SkipTest("Locale support on MacOSX is minimal")
      25          elif sys.platform.startswith("win"):
      26              tlocs = ("En", "English")
      27          else:
      28              tlocs = ("en_US.UTF-8", "en_US.ISO8859-1",
      29                       "en_US.US-ASCII", "en_US")
      30          try:
      31              oldlocale = locale.setlocale(locale.LC_NUMERIC)
      32              for tloc in tlocs:
      33                  try:
      34                      locale.setlocale(locale.LC_NUMERIC, tloc)
      35                  except locale.Error:
      36                      continue
      37                  break
      38              else:
      39                  raise unittest.SkipTest("Test locale not supported "
      40                                          "(tried %s)" % (', '.join(tlocs)))
      41              cls.enUS_locale = tloc
      42          finally:
      43              locale.setlocale(locale.LC_NUMERIC, oldlocale)
      44  
      45      def setUp(self):
      46          oldlocale = locale.setlocale(self.locale_type)
      47          self.addCleanup(locale.setlocale, self.locale_type, oldlocale)
      48          locale.setlocale(self.locale_type, self.enUS_locale)
      49          if verbose:
      50              print("testing with %r..." % self.enUS_locale, end=' ', flush=True)
      51  
      52  
      53  class ESC[4;38;5;81mBaseCookedTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      54      #
      55      # Base class for tests using cooked localeconv() values
      56      #
      57  
      58      def setUp(self):
      59          locale._override_localeconv = self.cooked_values
      60  
      61      def tearDown(self):
      62          locale._override_localeconv = {}
      63  
      64  class ESC[4;38;5;81mCCookedTest(ESC[4;38;5;149mBaseCookedTest):
      65      # A cooked "C" locale
      66  
      67      cooked_values = {
      68          'currency_symbol': '',
      69          'decimal_point': '.',
      70          'frac_digits': 127,
      71          'grouping': [],
      72          'int_curr_symbol': '',
      73          'int_frac_digits': 127,
      74          'mon_decimal_point': '',
      75          'mon_grouping': [],
      76          'mon_thousands_sep': '',
      77          'n_cs_precedes': 127,
      78          'n_sep_by_space': 127,
      79          'n_sign_posn': 127,
      80          'negative_sign': '',
      81          'p_cs_precedes': 127,
      82          'p_sep_by_space': 127,
      83          'p_sign_posn': 127,
      84          'positive_sign': '',
      85          'thousands_sep': ''
      86      }
      87  
      88  class ESC[4;38;5;81mEnUSCookedTest(ESC[4;38;5;149mBaseCookedTest):
      89      # A cooked "en_US" locale
      90  
      91      cooked_values = {
      92          'currency_symbol': '$',
      93          'decimal_point': '.',
      94          'frac_digits': 2,
      95          'grouping': [3, 3, 0],
      96          'int_curr_symbol': 'USD ',
      97          'int_frac_digits': 2,
      98          'mon_decimal_point': '.',
      99          'mon_grouping': [3, 3, 0],
     100          'mon_thousands_sep': ',',
     101          'n_cs_precedes': 1,
     102          'n_sep_by_space': 0,
     103          'n_sign_posn': 1,
     104          'negative_sign': '-',
     105          'p_cs_precedes': 1,
     106          'p_sep_by_space': 0,
     107          'p_sign_posn': 1,
     108          'positive_sign': '',
     109          'thousands_sep': ','
     110      }
     111  
     112  
     113  class ESC[4;38;5;81mFrFRCookedTest(ESC[4;38;5;149mBaseCookedTest):
     114      # A cooked "fr_FR" locale with a space character as decimal separator
     115      # and a non-ASCII currency symbol.
     116  
     117      cooked_values = {
     118          'currency_symbol': '\u20ac',
     119          'decimal_point': ',',
     120          'frac_digits': 2,
     121          'grouping': [3, 3, 0],
     122          'int_curr_symbol': 'EUR ',
     123          'int_frac_digits': 2,
     124          'mon_decimal_point': ',',
     125          'mon_grouping': [3, 3, 0],
     126          'mon_thousands_sep': ' ',
     127          'n_cs_precedes': 0,
     128          'n_sep_by_space': 1,
     129          'n_sign_posn': 1,
     130          'negative_sign': '-',
     131          'p_cs_precedes': 0,
     132          'p_sep_by_space': 1,
     133          'p_sign_posn': 1,
     134          'positive_sign': '',
     135          'thousands_sep': ' '
     136      }
     137  
     138  
     139  class ESC[4;38;5;81mBaseFormattingTest(ESC[4;38;5;149mobject):
     140      #
     141      # Utility functions for formatting tests
     142      #
     143  
     144      def _test_format_string(self, format, value, out, **format_opts):
     145          self.assertEqual(
     146              locale.format_string(format, value, **format_opts), out)
     147  
     148      def _test_currency(self, value, out, **format_opts):
     149          self.assertEqual(locale.currency(value, **format_opts), out)
     150  
     151  
     152  class ESC[4;38;5;81mEnUSNumberFormatting(ESC[4;38;5;149mBaseFormattingTest):
     153      # XXX there is a grouping + padding bug when the thousands separator
     154      # is empty but the grouping array contains values (e.g. Solaris 10)
     155  
     156      def setUp(self):
     157          self.sep = locale.localeconv()['thousands_sep']
     158  
     159      def test_grouping(self):
     160          self._test_format_string("%f", 1024, grouping=1, out='1%s024.000000' % self.sep)
     161          self._test_format_string("%f", 102, grouping=1, out='102.000000')
     162          self._test_format_string("%f", -42, grouping=1, out='-42.000000')
     163          self._test_format_string("%+f", -42, grouping=1, out='-42.000000')
     164  
     165      def test_grouping_and_padding(self):
     166          self._test_format_string("%20.f", -42, grouping=1, out='-42'.rjust(20))
     167          if self.sep:
     168              self._test_format_string("%+10.f", -4200, grouping=1,
     169                  out=('-4%s200' % self.sep).rjust(10))
     170              self._test_format_string("%-10.f", -4200, grouping=1,
     171                  out=('-4%s200' % self.sep).ljust(10))
     172  
     173      def test_integer_grouping(self):
     174          self._test_format_string("%d", 4200, grouping=True, out='4%s200' % self.sep)
     175          self._test_format_string("%+d", 4200, grouping=True, out='+4%s200' % self.sep)
     176          self._test_format_string("%+d", -4200, grouping=True, out='-4%s200' % self.sep)
     177  
     178      def test_integer_grouping_and_padding(self):
     179          self._test_format_string("%10d", 4200, grouping=True,
     180              out=('4%s200' % self.sep).rjust(10))
     181          self._test_format_string("%-10d", -4200, grouping=True,
     182              out=('-4%s200' % self.sep).ljust(10))
     183  
     184      def test_simple(self):
     185          self._test_format_string("%f", 1024, grouping=0, out='1024.000000')
     186          self._test_format_string("%f", 102, grouping=0, out='102.000000')
     187          self._test_format_string("%f", -42, grouping=0, out='-42.000000')
     188          self._test_format_string("%+f", -42, grouping=0, out='-42.000000')
     189  
     190      def test_padding(self):
     191          self._test_format_string("%20.f", -42, grouping=0, out='-42'.rjust(20))
     192          self._test_format_string("%+10.f", -4200, grouping=0, out='-4200'.rjust(10))
     193          self._test_format_string("%-10.f", 4200, grouping=0, out='4200'.ljust(10))
     194  
     195      def test_complex_formatting(self):
     196          # Spaces in formatting string
     197          self._test_format_string("One million is %i", 1000000, grouping=1,
     198              out='One million is 1%s000%s000' % (self.sep, self.sep))
     199          self._test_format_string("One  million is %i", 1000000, grouping=1,
     200              out='One  million is 1%s000%s000' % (self.sep, self.sep))
     201          # Dots in formatting string
     202          self._test_format_string(".%f.", 1000.0, out='.1000.000000.')
     203          # Padding
     204          if self.sep:
     205              self._test_format_string("-->  %10.2f", 4200, grouping=1,
     206                  out='-->  ' + ('4%s200.00' % self.sep).rjust(10))
     207          # Asterisk formats
     208          self._test_format_string("%10.*f", (2, 1000), grouping=0,
     209              out='1000.00'.rjust(10))
     210          if self.sep:
     211              self._test_format_string("%*.*f", (10, 2, 1000), grouping=1,
     212                  out=('1%s000.00' % self.sep).rjust(10))
     213          # Test more-in-one
     214          if self.sep:
     215              self._test_format_string("int %i float %.2f str %s",
     216                  (1000, 1000.0, 'str'), grouping=1,
     217                  out='int 1%s000 float 1%s000.00 str str' %
     218                  (self.sep, self.sep))
     219  
     220          self._test_format_string("total=%i%%", 100, out='total=100%')
     221          self._test_format_string("newline: %i\n", 3, out='newline: 3\n')
     222          self._test_format_string("extra: %ii", 3, out='extra: 3i')
     223  
     224  
     225  class ESC[4;38;5;81mTestLocaleFormatString(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     226      """General tests on locale.format_string"""
     227  
     228      def test_percent_escape(self):
     229          self.assertEqual(locale.format_string('%f%%', 1.0), '%f%%' % 1.0)
     230          self.assertEqual(locale.format_string('%d %f%%d', (1, 1.0)),
     231              '%d %f%%d' % (1, 1.0))
     232          self.assertEqual(locale.format_string('%(foo)s %%d', {'foo': 'bar'}),
     233              ('%(foo)s %%d' % {'foo': 'bar'}))
     234  
     235      def test_mapping(self):
     236          self.assertEqual(locale.format_string('%(foo)s bing.', {'foo': 'bar'}),
     237              ('%(foo)s bing.' % {'foo': 'bar'}))
     238          self.assertEqual(locale.format_string('%(foo)s', {'foo': 'bar'}),
     239              ('%(foo)s' % {'foo': 'bar'}))
     240  
     241  
     242  
     243  class ESC[4;38;5;81mTestNumberFormatting(ESC[4;38;5;149mBaseLocalizedTest, ESC[4;38;5;149mEnUSNumberFormatting):
     244      # Test number formatting with a real English locale.
     245  
     246      locale_type = locale.LC_NUMERIC
     247  
     248      def setUp(self):
     249          BaseLocalizedTest.setUp(self)
     250          EnUSNumberFormatting.setUp(self)
     251  
     252  
     253  class ESC[4;38;5;81mTestEnUSNumberFormatting(ESC[4;38;5;149mEnUSCookedTest, ESC[4;38;5;149mEnUSNumberFormatting):
     254      # Test number formatting with a cooked "en_US" locale.
     255  
     256      def setUp(self):
     257          EnUSCookedTest.setUp(self)
     258          EnUSNumberFormatting.setUp(self)
     259  
     260      def test_currency(self):
     261          self._test_currency(50000, "$50000.00")
     262          self._test_currency(50000, "$50,000.00", grouping=True)
     263          self._test_currency(50000, "USD 50,000.00",
     264              grouping=True, international=True)
     265  
     266  
     267  class ESC[4;38;5;81mTestCNumberFormatting(ESC[4;38;5;149mCCookedTest, ESC[4;38;5;149mBaseFormattingTest):
     268      # Test number formatting with a cooked "C" locale.
     269  
     270      def test_grouping(self):
     271          self._test_format_string("%.2f", 12345.67, grouping=True, out='12345.67')
     272  
     273      def test_grouping_and_padding(self):
     274          self._test_format_string("%9.2f", 12345.67, grouping=True, out=' 12345.67')
     275  
     276  
     277  class ESC[4;38;5;81mTestFrFRNumberFormatting(ESC[4;38;5;149mFrFRCookedTest, ESC[4;38;5;149mBaseFormattingTest):
     278      # Test number formatting with a cooked "fr_FR" locale.
     279  
     280      def test_decimal_point(self):
     281          self._test_format_string("%.2f", 12345.67, out='12345,67')
     282  
     283      def test_grouping(self):
     284          self._test_format_string("%.2f", 345.67, grouping=True, out='345,67')
     285          self._test_format_string("%.2f", 12345.67, grouping=True, out='12 345,67')
     286  
     287      def test_grouping_and_padding(self):
     288          self._test_format_string("%6.2f", 345.67, grouping=True, out='345,67')
     289          self._test_format_string("%7.2f", 345.67, grouping=True, out=' 345,67')
     290          self._test_format_string("%8.2f", 12345.67, grouping=True, out='12 345,67')
     291          self._test_format_string("%9.2f", 12345.67, grouping=True, out='12 345,67')
     292          self._test_format_string("%10.2f", 12345.67, grouping=True, out=' 12 345,67')
     293          self._test_format_string("%-6.2f", 345.67, grouping=True, out='345,67')
     294          self._test_format_string("%-7.2f", 345.67, grouping=True, out='345,67 ')
     295          self._test_format_string("%-8.2f", 12345.67, grouping=True, out='12 345,67')
     296          self._test_format_string("%-9.2f", 12345.67, grouping=True, out='12 345,67')
     297          self._test_format_string("%-10.2f", 12345.67, grouping=True, out='12 345,67 ')
     298  
     299      def test_integer_grouping(self):
     300          self._test_format_string("%d", 200, grouping=True, out='200')
     301          self._test_format_string("%d", 4200, grouping=True, out='4 200')
     302  
     303      def test_integer_grouping_and_padding(self):
     304          self._test_format_string("%4d", 4200, grouping=True, out='4 200')
     305          self._test_format_string("%5d", 4200, grouping=True, out='4 200')
     306          self._test_format_string("%10d", 4200, grouping=True, out='4 200'.rjust(10))
     307          self._test_format_string("%-4d", 4200, grouping=True, out='4 200')
     308          self._test_format_string("%-5d", 4200, grouping=True, out='4 200')
     309          self._test_format_string("%-10d", 4200, grouping=True, out='4 200'.ljust(10))
     310  
     311      def test_currency(self):
     312          euro = '\u20ac'
     313          self._test_currency(50000, "50000,00 " + euro)
     314          self._test_currency(50000, "50 000,00 " + euro, grouping=True)
     315          self._test_currency(50000, "50 000,00 EUR",
     316              grouping=True, international=True)
     317  
     318  
     319  class ESC[4;38;5;81mTestCollation(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     320      # Test string collation functions
     321  
     322      def test_strcoll(self):
     323          self.assertLess(locale.strcoll('a', 'b'), 0)
     324          self.assertEqual(locale.strcoll('a', 'a'), 0)
     325          self.assertGreater(locale.strcoll('b', 'a'), 0)
     326          # embedded null character
     327          self.assertRaises(ValueError, locale.strcoll, 'a\0', 'a')
     328          self.assertRaises(ValueError, locale.strcoll, 'a', 'a\0')
     329  
     330      def test_strxfrm(self):
     331          self.assertLess(locale.strxfrm('a'), locale.strxfrm('b'))
     332          # embedded null character
     333          self.assertRaises(ValueError, locale.strxfrm, 'a\0')
     334  
     335  
     336  class ESC[4;38;5;81mTestEnUSCollation(ESC[4;38;5;149mBaseLocalizedTest, ESC[4;38;5;149mTestCollation):
     337      # Test string collation functions with a real English locale
     338  
     339      locale_type = locale.LC_ALL
     340  
     341      def setUp(self):
     342          enc = codecs.lookup(locale.getencoding() or 'ascii').name
     343          if enc not in ('utf-8', 'iso8859-1', 'cp1252'):
     344              raise unittest.SkipTest('encoding not suitable')
     345          if enc != 'iso8859-1' and (sys.platform == 'darwin' or is_android or
     346                                     sys.platform.startswith('freebsd')):
     347              raise unittest.SkipTest('wcscoll/wcsxfrm have known bugs')
     348          BaseLocalizedTest.setUp(self)
     349  
     350      @unittest.skipIf(sys.platform.startswith('aix'),
     351                       'bpo-29972: broken test on AIX')
     352      @unittest.skipIf(
     353          is_emscripten or is_wasi,
     354          "musl libc issue on Emscripten/WASI, bpo-46390"
     355      )
     356      def test_strcoll_with_diacritic(self):
     357          self.assertLess(locale.strcoll('à', 'b'), 0)
     358  
     359      @unittest.skipIf(sys.platform.startswith('aix'),
     360                       'bpo-29972: broken test on AIX')
     361      @unittest.skipIf(
     362          is_emscripten or is_wasi,
     363          "musl libc issue on Emscripten/WASI, bpo-46390"
     364      )
     365      def test_strxfrm_with_diacritic(self):
     366          self.assertLess(locale.strxfrm('à'), locale.strxfrm('b'))
     367  
     368  
     369  class ESC[4;38;5;81mNormalizeTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     370      def check(self, localename, expected):
     371          self.assertEqual(locale.normalize(localename), expected, msg=localename)
     372  
     373      def test_locale_alias(self):
     374          for localename, alias in locale.locale_alias.items():
     375              with self.subTest(locale=(localename, alias)):
     376                  self.check(localename, alias)
     377  
     378      def test_empty(self):
     379          self.check('', '')
     380  
     381      def test_c(self):
     382          self.check('c', 'C')
     383          self.check('posix', 'C')
     384  
     385      def test_english(self):
     386          self.check('en', 'en_US.ISO8859-1')
     387          self.check('EN', 'en_US.ISO8859-1')
     388          self.check('en.iso88591', 'en_US.ISO8859-1')
     389          self.check('en_US', 'en_US.ISO8859-1')
     390          self.check('en_us', 'en_US.ISO8859-1')
     391          self.check('en_GB', 'en_GB.ISO8859-1')
     392          self.check('en_US.UTF-8', 'en_US.UTF-8')
     393          self.check('en_US.utf8', 'en_US.UTF-8')
     394          self.check('en_US:UTF-8', 'en_US.UTF-8')
     395          self.check('en_US.ISO8859-1', 'en_US.ISO8859-1')
     396          self.check('en_US.US-ASCII', 'en_US.ISO8859-1')
     397          self.check('en_US.88591', 'en_US.ISO8859-1')
     398          self.check('en_US.885915', 'en_US.ISO8859-15')
     399          self.check('english', 'en_EN.ISO8859-1')
     400          self.check('english_uk.ascii', 'en_GB.ISO8859-1')
     401  
     402      def test_hyphenated_encoding(self):
     403          self.check('az_AZ.iso88599e', 'az_AZ.ISO8859-9E')
     404          self.check('az_AZ.ISO8859-9E', 'az_AZ.ISO8859-9E')
     405          self.check('tt_RU.koi8c', 'tt_RU.KOI8-C')
     406          self.check('tt_RU.KOI8-C', 'tt_RU.KOI8-C')
     407          self.check('lo_LA.cp1133', 'lo_LA.IBM-CP1133')
     408          self.check('lo_LA.ibmcp1133', 'lo_LA.IBM-CP1133')
     409          self.check('lo_LA.IBM-CP1133', 'lo_LA.IBM-CP1133')
     410          self.check('uk_ua.microsoftcp1251', 'uk_UA.CP1251')
     411          self.check('uk_ua.microsoft-cp1251', 'uk_UA.CP1251')
     412          self.check('ka_ge.georgianacademy', 'ka_GE.GEORGIAN-ACADEMY')
     413          self.check('ka_GE.GEORGIAN-ACADEMY', 'ka_GE.GEORGIAN-ACADEMY')
     414          self.check('cs_CZ.iso88592', 'cs_CZ.ISO8859-2')
     415          self.check('cs_CZ.ISO8859-2', 'cs_CZ.ISO8859-2')
     416  
     417      def test_euro_modifier(self):
     418          self.check('de_DE@euro', 'de_DE.ISO8859-15')
     419          self.check('en_US.ISO8859-15@euro', 'en_US.ISO8859-15')
     420          self.check('de_DE.utf8@euro', 'de_DE.UTF-8')
     421  
     422      def test_latin_modifier(self):
     423          self.check('be_BY.UTF-8@latin', 'be_BY.UTF-8@latin')
     424          self.check('sr_RS.UTF-8@latin', 'sr_RS.UTF-8@latin')
     425          self.check('sr_RS.UTF-8@latn', 'sr_RS.UTF-8@latin')
     426  
     427      def test_valencia_modifier(self):
     428          self.check('ca_ES.UTF-8@valencia', 'ca_ES.UTF-8@valencia')
     429          self.check('ca_ES@valencia', 'ca_ES.UTF-8@valencia')
     430          self.check('ca@valencia', 'ca_ES.ISO8859-1@valencia')
     431  
     432      def test_devanagari_modifier(self):
     433          self.check('ks_IN.UTF-8@devanagari', 'ks_IN.UTF-8@devanagari')
     434          self.check('ks_IN@devanagari', 'ks_IN.UTF-8@devanagari')
     435          self.check('ks@devanagari', 'ks_IN.UTF-8@devanagari')
     436          self.check('ks_IN.UTF-8', 'ks_IN.UTF-8')
     437          self.check('ks_IN', 'ks_IN.UTF-8')
     438          self.check('ks', 'ks_IN.UTF-8')
     439          self.check('sd_IN.UTF-8@devanagari', 'sd_IN.UTF-8@devanagari')
     440          self.check('sd_IN@devanagari', 'sd_IN.UTF-8@devanagari')
     441          self.check('sd@devanagari', 'sd_IN.UTF-8@devanagari')
     442          self.check('sd_IN.UTF-8', 'sd_IN.UTF-8')
     443          self.check('sd_IN', 'sd_IN.UTF-8')
     444          self.check('sd', 'sd_IN.UTF-8')
     445  
     446      def test_euc_encoding(self):
     447          self.check('ja_jp.euc', 'ja_JP.eucJP')
     448          self.check('ja_jp.eucjp', 'ja_JP.eucJP')
     449          self.check('ko_kr.euc', 'ko_KR.eucKR')
     450          self.check('ko_kr.euckr', 'ko_KR.eucKR')
     451          self.check('zh_cn.euc', 'zh_CN.eucCN')
     452          self.check('zh_tw.euc', 'zh_TW.eucTW')
     453          self.check('zh_tw.euctw', 'zh_TW.eucTW')
     454  
     455      def test_japanese(self):
     456          self.check('ja', 'ja_JP.eucJP')
     457          self.check('ja.jis', 'ja_JP.JIS7')
     458          self.check('ja.sjis', 'ja_JP.SJIS')
     459          self.check('ja_jp', 'ja_JP.eucJP')
     460          self.check('ja_jp.ajec', 'ja_JP.eucJP')
     461          self.check('ja_jp.euc', 'ja_JP.eucJP')
     462          self.check('ja_jp.eucjp', 'ja_JP.eucJP')
     463          self.check('ja_jp.iso-2022-jp', 'ja_JP.JIS7')
     464          self.check('ja_jp.iso2022jp', 'ja_JP.JIS7')
     465          self.check('ja_jp.jis', 'ja_JP.JIS7')
     466          self.check('ja_jp.jis7', 'ja_JP.JIS7')
     467          self.check('ja_jp.mscode', 'ja_JP.SJIS')
     468          self.check('ja_jp.pck', 'ja_JP.SJIS')
     469          self.check('ja_jp.sjis', 'ja_JP.SJIS')
     470          self.check('ja_jp.ujis', 'ja_JP.eucJP')
     471          self.check('ja_jp.utf8', 'ja_JP.UTF-8')
     472          self.check('japan', 'ja_JP.eucJP')
     473          self.check('japanese', 'ja_JP.eucJP')
     474          self.check('japanese-euc', 'ja_JP.eucJP')
     475          self.check('japanese.euc', 'ja_JP.eucJP')
     476          self.check('japanese.sjis', 'ja_JP.SJIS')
     477          self.check('jp_jp', 'ja_JP.eucJP')
     478  
     479  
     480  class ESC[4;38;5;81mTestMiscellaneous(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     481      def test_defaults_UTF8(self):
     482          # Issue #18378: on (at least) macOS setting LC_CTYPE to "UTF-8" is
     483          # valid. Furthermore LC_CTYPE=UTF is used by the UTF-8 locale coercing
     484          # during interpreter startup (on macOS).
     485          import _locale
     486          import os
     487  
     488          self.assertEqual(locale._parse_localename('UTF-8'), (None, 'UTF-8'))
     489  
     490          if hasattr(_locale, '_getdefaultlocale'):
     491              orig_getlocale = _locale._getdefaultlocale
     492              del _locale._getdefaultlocale
     493          else:
     494              orig_getlocale = None
     495  
     496          orig_env = {}
     497          try:
     498              for key in ('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE'):
     499                  if key in os.environ:
     500                      orig_env[key] = os.environ[key]
     501                      del os.environ[key]
     502  
     503              os.environ['LC_CTYPE'] = 'UTF-8'
     504  
     505              with check_warnings(('', DeprecationWarning)):
     506                  self.assertEqual(locale.getdefaultlocale(), (None, 'UTF-8'))
     507  
     508          finally:
     509              for k in orig_env:
     510                  os.environ[k] = orig_env[k]
     511  
     512              if 'LC_CTYPE' not in orig_env:
     513                  del os.environ['LC_CTYPE']
     514  
     515              if orig_getlocale is not None:
     516                  _locale._getdefaultlocale = orig_getlocale
     517  
     518      def test_getencoding(self):
     519          # Invoke getencoding to make sure it does not cause exceptions.
     520          enc = locale.getencoding()
     521          self.assertIsInstance(enc, str)
     522          self.assertNotEqual(enc, "")
     523          # make sure it is valid
     524          codecs.lookup(enc)
     525  
     526      def test_getpreferredencoding(self):
     527          # Invoke getpreferredencoding to make sure it does not cause exceptions.
     528          enc = locale.getpreferredencoding()
     529          if enc:
     530              # If encoding non-empty, make sure it is valid
     531              codecs.lookup(enc)
     532  
     533      def test_strcoll_3303(self):
     534          # test crasher from bug #3303
     535          self.assertRaises(TypeError, locale.strcoll, "a", None)
     536          self.assertRaises(TypeError, locale.strcoll, b"a", None)
     537  
     538      def test_setlocale_category(self):
     539          locale.setlocale(locale.LC_ALL)
     540          locale.setlocale(locale.LC_TIME)
     541          locale.setlocale(locale.LC_CTYPE)
     542          locale.setlocale(locale.LC_COLLATE)
     543          locale.setlocale(locale.LC_MONETARY)
     544          locale.setlocale(locale.LC_NUMERIC)
     545  
     546          # crasher from bug #7419
     547          self.assertRaises(locale.Error, locale.setlocale, 12345)
     548  
     549      def test_getsetlocale_issue1813(self):
     550          # Issue #1813: setting and getting the locale under a Turkish locale
     551          oldlocale = locale.setlocale(locale.LC_CTYPE)
     552          self.addCleanup(locale.setlocale, locale.LC_CTYPE, oldlocale)
     553          try:
     554              locale.setlocale(locale.LC_CTYPE, 'tr_TR')
     555          except locale.Error:
     556              # Unsupported locale on this system
     557              self.skipTest('test needs Turkish locale')
     558          loc = locale.getlocale(locale.LC_CTYPE)
     559          if verbose:
     560              print('testing with %a' % (loc,), end=' ', flush=True)
     561          try:
     562              locale.setlocale(locale.LC_CTYPE, loc)
     563          except locale.Error as exc:
     564              # bpo-37945: setlocale(LC_CTYPE) fails with getlocale(LC_CTYPE)
     565              # and the tr_TR locale on Windows. getlocale() builds a locale
     566              # which is not recognize by setlocale().
     567              self.skipTest(f"setlocale(LC_CTYPE, {loc!r}) failed: {exc!r}")
     568          self.assertEqual(loc, locale.getlocale(locale.LC_CTYPE))
     569  
     570      def test_invalid_locale_format_in_localetuple(self):
     571          with self.assertRaises(TypeError):
     572              locale.setlocale(locale.LC_ALL, b'fi_FI')
     573  
     574      def test_invalid_iterable_in_localetuple(self):
     575          with self.assertRaises(TypeError):
     576              locale.setlocale(locale.LC_ALL, (b'not', b'valid'))
     577  
     578  
     579  class ESC[4;38;5;81mBaseDelocalizeTest(ESC[4;38;5;149mBaseLocalizedTest):
     580  
     581      def _test_delocalize(self, value, out):
     582          self.assertEqual(locale.delocalize(value), out)
     583  
     584      def _test_atof(self, value, out):
     585          self.assertEqual(locale.atof(value), out)
     586  
     587      def _test_atoi(self, value, out):
     588          self.assertEqual(locale.atoi(value), out)
     589  
     590  
     591  class ESC[4;38;5;81mTestEnUSDelocalize(ESC[4;38;5;149mEnUSCookedTest, ESC[4;38;5;149mBaseDelocalizeTest):
     592  
     593      def test_delocalize(self):
     594          self._test_delocalize('50000.00', '50000.00')
     595          self._test_delocalize('50,000.00', '50000.00')
     596  
     597      def test_atof(self):
     598          self._test_atof('50000.00', 50000.)
     599          self._test_atof('50,000.00', 50000.)
     600  
     601      def test_atoi(self):
     602          self._test_atoi('50000', 50000)
     603          self._test_atoi('50,000', 50000)
     604  
     605  
     606  class ESC[4;38;5;81mTestCDelocalizeTest(ESC[4;38;5;149mCCookedTest, ESC[4;38;5;149mBaseDelocalizeTest):
     607  
     608      def test_delocalize(self):
     609          self._test_delocalize('50000.00', '50000.00')
     610  
     611      def test_atof(self):
     612          self._test_atof('50000.00', 50000.)
     613  
     614      def test_atoi(self):
     615          self._test_atoi('50000', 50000)
     616  
     617  
     618  class ESC[4;38;5;81mTestfrFRDelocalizeTest(ESC[4;38;5;149mFrFRCookedTest, ESC[4;38;5;149mBaseDelocalizeTest):
     619  
     620      def test_delocalize(self):
     621          self._test_delocalize('50000,00', '50000.00')
     622          self._test_delocalize('50 000,00', '50000.00')
     623  
     624      def test_atof(self):
     625          self._test_atof('50000,00', 50000.)
     626          self._test_atof('50 000,00', 50000.)
     627  
     628      def test_atoi(self):
     629          self._test_atoi('50000', 50000)
     630          self._test_atoi('50 000', 50000)
     631  
     632  
     633  class ESC[4;38;5;81mBaseLocalizeTest(ESC[4;38;5;149mBaseLocalizedTest):
     634  
     635      def _test_localize(self, value, out, grouping=False):
     636          self.assertEqual(locale.localize(value, grouping=grouping), out)
     637  
     638  
     639  class ESC[4;38;5;81mTestEnUSLocalize(ESC[4;38;5;149mEnUSCookedTest, ESC[4;38;5;149mBaseLocalizeTest):
     640  
     641      def test_localize(self):
     642          self._test_localize('50000.00', '50000.00')
     643          self._test_localize(
     644              '{0:.16f}'.format(Decimal('1.15')), '1.1500000000000000')
     645  
     646  
     647  class ESC[4;38;5;81mTestCLocalize(ESC[4;38;5;149mCCookedTest, ESC[4;38;5;149mBaseLocalizeTest):
     648  
     649      def test_localize(self):
     650          self._test_localize('50000.00', '50000.00')
     651  
     652  
     653  class ESC[4;38;5;81mTestfrFRLocalize(ESC[4;38;5;149mFrFRCookedTest, ESC[4;38;5;149mBaseLocalizeTest):
     654  
     655      def test_localize(self):
     656          self._test_localize('50000.00', '50000,00')
     657          self._test_localize('50000.00', '50 000,00', grouping=True)
     658  
     659  
     660  if __name__ == '__main__':
     661      unittest.main()