|
1 from test.test_support import verbose, TestSkipped, run_unittest |
|
2 from _locale import (setlocale, LC_NUMERIC, RADIXCHAR, THOUSEP, nl_langinfo, |
|
3 localeconv, Error) |
|
4 import unittest |
|
5 from platform import uname |
|
6 |
|
7 if uname()[0] == "Darwin": |
|
8 maj, min, mic = [int(part) for part in uname()[2].split(".")] |
|
9 if (maj, min, mic) < (8, 0, 0): |
|
10 raise TestSkipped("locale support broken for OS X < 10.4") |
|
11 |
|
12 candidate_locales = ['es_UY', 'fr_FR', 'fi_FI', 'es_CO', 'pt_PT', 'it_IT', |
|
13 'et_EE', 'es_PY', 'no_NO', 'nl_NL', 'lv_LV', 'el_GR', 'be_BY', 'fr_BE', |
|
14 'ro_RO', 'ru_UA', 'ru_RU', 'es_VE', 'ca_ES', 'se_NO', 'es_EC', 'id_ID', |
|
15 'ka_GE', 'es_CL', 'hu_HU', 'wa_BE', 'lt_LT', 'sl_SI', 'hr_HR', 'es_AR', |
|
16 'es_ES', 'oc_FR', 'gl_ES', 'bg_BG', 'is_IS', 'mk_MK', 'de_AT', 'pt_BR', |
|
17 'da_DK', 'nn_NO', 'cs_CZ', 'de_LU', 'es_BO', 'sq_AL', 'sk_SK', 'fr_CH', |
|
18 'de_DE', 'sr_YU', 'br_FR', 'nl_BE', 'sv_FI', 'pl_PL', 'fr_CA', 'fo_FO', |
|
19 'bs_BA', 'fr_LU', 'kl_GL', 'fa_IR', 'de_BE', 'sv_SE', 'it_CH', 'uk_UA', |
|
20 'eu_ES', 'vi_VN', 'af_ZA', 'nb_NO', 'en_DK', 'tg_TJ', 'en_US', |
|
21 'es_ES.ISO8859-1', 'fr_FR.ISO8859-15', 'ru_RU.KOI8-R', 'ko_KR.eucKR'] |
|
22 |
|
23 # List known locale values to test against when available. |
|
24 # Dict formatted as ``<locale> : (<decimal_point>, <thousands_sep>)``. If a |
|
25 # value is not known, use '' . |
|
26 known_numerics = {'fr_FR' : (',', ''), 'en_US':('.', ',')} |
|
27 |
|
28 class _LocaleTests(unittest.TestCase): |
|
29 |
|
30 def setUp(self): |
|
31 self.oldlocale = setlocale(LC_NUMERIC) |
|
32 |
|
33 def tearDown(self): |
|
34 setlocale(LC_NUMERIC, self.oldlocale) |
|
35 |
|
36 # Want to know what value was calculated, what it was compared against, |
|
37 # what function was used for the calculation, what type of data was used, |
|
38 # the locale that was supposedly set, and the actual locale that is set. |
|
39 lc_numeric_err_msg = "%s != %s (%s for %s; set to %s, using %s)" |
|
40 |
|
41 def numeric_tester(self, calc_type, calc_value, data_type, used_locale): |
|
42 """Compare calculation against known value, if available""" |
|
43 try: |
|
44 set_locale = setlocale(LC_NUMERIC) |
|
45 except Error: |
|
46 set_locale = "<not able to determine>" |
|
47 known_value = known_numerics.get(used_locale, |
|
48 ('', ''))[data_type is 'thousands_sep'] |
|
49 if known_value and calc_value: |
|
50 self.assertEquals(calc_value, known_value, |
|
51 self.lc_numeric_err_msg % ( |
|
52 calc_value, known_value, |
|
53 calc_type, data_type, set_locale, |
|
54 used_locale)) |
|
55 |
|
56 def test_lc_numeric_nl_langinfo(self): |
|
57 # Test nl_langinfo against known values |
|
58 for loc in candidate_locales: |
|
59 try: |
|
60 setlocale(LC_NUMERIC, loc) |
|
61 except Error: |
|
62 continue |
|
63 for li, lc in ((RADIXCHAR, "decimal_point"), |
|
64 (THOUSEP, "thousands_sep")): |
|
65 self.numeric_tester('nl_langinfo', nl_langinfo(li), lc, loc) |
|
66 |
|
67 def test_lc_numeric_localeconv(self): |
|
68 # Test localeconv against known values |
|
69 for loc in candidate_locales: |
|
70 try: |
|
71 setlocale(LC_NUMERIC, loc) |
|
72 except Error: |
|
73 continue |
|
74 for li, lc in ((RADIXCHAR, "decimal_point"), |
|
75 (THOUSEP, "thousands_sep")): |
|
76 self.numeric_tester('localeconv', localeconv()[lc], lc, loc) |
|
77 |
|
78 def test_lc_numeric_basic(self): |
|
79 # Test nl_langinfo against localeconv |
|
80 for loc in candidate_locales: |
|
81 try: |
|
82 setlocale(LC_NUMERIC, loc) |
|
83 except Error: |
|
84 continue |
|
85 for li, lc in ((RADIXCHAR, "decimal_point"), |
|
86 (THOUSEP, "thousands_sep")): |
|
87 nl_radixchar = nl_langinfo(li) |
|
88 li_radixchar = localeconv()[lc] |
|
89 try: |
|
90 set_locale = setlocale(LC_NUMERIC) |
|
91 except Error: |
|
92 set_locale = "<not able to determine>" |
|
93 self.assertEquals(nl_radixchar, li_radixchar, |
|
94 "%s (nl_langinfo) != %s (localeconv) " |
|
95 "(set to %s, using %s)" % ( |
|
96 nl_radixchar, li_radixchar, |
|
97 loc, set_locale)) |
|
98 |
|
99 def test_float_parsing(self): |
|
100 # Bug #1391872: Test whether float parsing is okay on European |
|
101 # locales. |
|
102 for loc in candidate_locales: |
|
103 try: |
|
104 setlocale(LC_NUMERIC, loc) |
|
105 except Error: |
|
106 continue |
|
107 |
|
108 # Ignore buggy locale databases. (Mac OS 10.4 and some other BSDs) |
|
109 if loc == 'eu_ES' and localeconv()['decimal_point'] == "' ": |
|
110 continue |
|
111 |
|
112 self.assertEquals(int(eval('3.14') * 100), 314, |
|
113 "using eval('3.14') failed for %s" % loc) |
|
114 self.assertEquals(int(float('3.14') * 100), 314, |
|
115 "using float('3.14') failed for %s" % loc) |
|
116 if localeconv()['decimal_point'] != '.': |
|
117 self.assertRaises(ValueError, float, |
|
118 localeconv()['decimal_point'].join(['1', '23'])) |
|
119 |
|
120 def test_main(): |
|
121 run_unittest(_LocaleTests) |
|
122 |
|
123 if __name__ == '__main__': |
|
124 test_main() |