Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(43163)

Side by Side Diff: Modules/_decimal/tests/formathelper.py

Issue 7652: Merge C version of decimal into py3k.
Patch Set: Created 7 years, 6 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Modules/_decimal/tests/deccheck.py ('k') | Modules/_decimal/tests/randdec.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #
2 # Copyright (c) 2008-2010 Stefan Krah. All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions
6 # are met:
7 #
8 # 1. Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 #
11 # 2. Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
14 #
15 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
16 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 # SUCH DAMAGE.
26 #
27
28
29 # Generate PEP-3101 format strings.
30
31
32 import os, sys, locale, random
33 import platform, subprocess
34 from test.support import import_fresh_module
35 from distutils.spawn import find_executable
36
37 C = import_fresh_module('decimal', fresh=['_decimal'])
38 P = import_fresh_module('decimal', blocked=['_decimal'])
39
40
41 windows_lang_strings = [
42 "chinese", "chinese-simplified", "chinese-traditional", "czech", "danish",
43 "dutch", "belgian", "english", "australian", "canadian", "english-nz",
44 "english-uk", "english-us", "finnish", "french", "french-belgian",
45 "french-canadian", "french-swiss", "german", "german-austrian",
46 "german-swiss", "greek", "hungarian", "icelandic", "italian", "italian-swiss",
47 "japanese", "korean", "norwegian", "norwegian-bokmal", "norwegian-nynorsk",
48 "polish", "portuguese", "portuguese-brazil", "russian", "slovak", "spanish",
49 "spanish-mexican", "spanish-modern", "swedish", "turkish",
50 ]
51
52 preferred_encoding = {
53 'cs_CZ': 'ISO8859-2',
54 'cs_CZ.iso88592': 'ISO8859-2',
55 'czech': 'ISO8859-2',
56 'eesti': 'ISO8859-1',
57 'estonian': 'ISO8859-1',
58 'et_EE': 'ISO8859-15',
59 'et_EE.ISO-8859-15': 'ISO8859-15',
60 'et_EE.iso885915': 'ISO8859-15',
61 'et_EE.iso88591': 'ISO8859-1',
62 'fi_FI.iso88591': 'ISO8859-1',
63 'fi_FI': 'ISO8859-15',
64 'fi_FI@euro': 'ISO8859-15',
65 'fi_FI.iso885915@euro': 'ISO8859-15',
66 'finnish': 'ISO8859-1',
67 'lv_LV': 'ISO8859-13',
68 'lv_LV.iso885913': 'ISO8859-13',
69 'nb_NO': 'ISO8859-1',
70 'nb_NO.iso88591': 'ISO8859-1',
71 'bokmal': 'ISO8859-1',
72 'nn_NO': 'ISO8859-1',
73 'nn_NO.iso88591': 'ISO8859-1',
74 'no_NO': 'ISO8859-1',
75 'norwegian': 'ISO8859-1',
76 'nynorsk': 'ISO8859-1',
77 'ru_RU': 'ISO8859-5',
78 'ru_RU.iso88595': 'ISO8859-5',
79 'russian': 'ISO8859-5',
80 'ru_RU.KOI8-R': 'KOI8-R',
81 'ru_RU.koi8r': 'KOI8-R',
82 'ru_RU.CP1251': 'CP1251',
83 'ru_RU.cp1251': 'CP1251',
84 'sk_SK': 'ISO8859-2',
85 'sk_SK.iso88592': 'ISO8859-2',
86 'slovak': 'ISO8859-2',
87 'sv_FI': 'ISO8859-1',
88 'sv_FI.iso88591': 'ISO8859-1',
89 'sv_FI@euro': 'ISO8859-15',
90 'sv_FI.iso885915@euro': 'ISO8859-15',
91 'uk_UA': 'KOI8-U',
92 'uk_UA.koi8u': 'KOI8-U'
93 }
94
95 integers = [
96 "",
97 "1",
98 "12",
99 "123",
100 "1234",
101 "12345",
102 "123456",
103 "1234567",
104 "12345678",
105 "123456789",
106 "1234567890",
107 "12345678901",
108 "123456789012",
109 "1234567890123",
110 "12345678901234",
111 "123456789012345",
112 "1234567890123456",
113 "12345678901234567",
114 "123456789012345678",
115 "1234567890123456789",
116 "12345678901234567890",
117 "123456789012345678901",
118 "1234567890123456789012",
119 ]
120
121 numbers = [
122 "0", "-0", "+0",
123 "0.0", "-0.0", "+0.0",
124 "0e0", "-0e0", "+0e0",
125 ".0", "-.0",
126 ".1", "-.1",
127 "1.1", "-1.1",
128 "1e1", "-1e1"
129 ]
130
131 # Get the list of available locales.
132 if platform.system() == 'Windows':
133 locale_list = windows_lang_strings
134 else:
135 locale_list = ['C']
136 if os.path.isfile("/var/lib/locales/supported.d/local"):
137 # On Ubuntu, `locale -a` gives the wrong case for some locales,
138 # so we get the correct names directly:
139 with open("/var/lib/locales/supported.d/local") as f:
140 locale_list = [loc.split()[0] for loc in f.readlines() \
141 if not loc.startswith('#')]
142 elif find_executable('locale'):
143 locale_list = subprocess.Popen(["locale", "-a"],
144 stdout=subprocess.PIPE).communicate()[0]
145 try:
146 locale_list = locale_list.decode()
147 except UnicodeDecodeError:
148 # Some distributions insist on using latin-1 characters
149 # in their locale names.
150 locale_list = locale_list.decode('latin-1')
151 locale_list = locale_list.split('\n')
152 try:
153 locale_list.remove('')
154 except ValueError:
155 pass
156
157 # Debian
158 if os.path.isfile("/etc/locale.alias"):
159 with open("/etc/locale.alias") as f:
160 while 1:
161 try:
162 line = f.readline()
163 except UnicodeDecodeError:
164 continue
165 if line == "":
166 break
167 if line.startswith('#'):
168 continue
169 x = line.split()
170 if len(x) == 2:
171 if x[0] in locale_list:
172 locale_list.remove(x[0])
173
174 # FreeBSD
175 if platform.system() == 'FreeBSD':
176 # http://www.freebsd.org/cgi/query-pr.cgi?pr=142173
177 # en_GB.US-ASCII has 163 as the currency symbol.
178 for loc in ['it_CH.ISO8859-1', 'it_CH.ISO8859-15', 'it_CH.UTF-8',
179 'it_IT.ISO8859-1', 'it_IT.ISO8859-15', 'it_IT.UTF-8',
180 'sl_SI.ISO8859-2', 'sl_SI.UTF-8',
181 'en_GB.US-ASCII']:
182 try:
183 locale_list.remove(loc)
184 except ValueError:
185 pass
186
187 # Print a testcase in the format of the IBM tests (for runtest.c):
188 def get_preferred_encoding():
189 loc = locale.setlocale(locale.LC_CTYPE)
190 if loc in preferred_encoding:
191 return preferred_encoding[loc]
192 else:
193 return locale.getpreferredencoding()
194
195 def printit(testno, s, fmt, encoding=None):
196 if not encoding:
197 encoding = get_preferred_encoding()
198 try:
199 result = format(P.Decimal(s), fmt)
200 fmt = str(fmt.encode(encoding))[2:-1]
201 result = str(result.encode(encoding))[2:-1]
202 if "'" in result:
203 sys.stdout.write("xfmt%d format %s '%s' -> \"%s\"\n"
204 % (testno, s, fmt, result))
205 else:
206 sys.stdout.write("xfmt%d format %s '%s' -> '%s'\n"
207 % (testno, s, fmt, result))
208 except Exception as err:
209 sys.stderr.write("%s %s %s\n" % (err, s, fmt))
210
211
212 # Check if an integer can be converted to a valid fill character.
213 def check_fillchar(i):
214 try:
215 c = chr(i)
216 c.encode('utf-8').decode()
217 format(P.Decimal(0), c + '<19g')
218 if c in ("'", '"', '\\'):
219 return None
220 return c
221 except:
222 return None
223
224 # Generate all unicode characters that are accepted as
225 # fill characters by decimal.py.
226 def all_fillchars():
227 for i in range(32, 0x110002):
228 c = check_fillchar(i)
229 if c: yield c
230
231 # Return random fill character.
232 def rand_fillchar():
233 while 1:
234 i = random.randrange(32, 0x110002)
235 c = check_fillchar(i)
236 if c: return c
237
238 # Generate random format strings
239 # [[fill]align][sign][#][0][width][.precision][type]
240 def rand_format(fill, typespec='EeGgFfn%'):
241 active = sorted(random.sample(range(7), random.randrange(8)))
242 have_align = 0
243 s = ''
244 for elem in active:
245 if elem == 0: # fill+align
246 s += fill
247 s += random.choice('<>=^')
248 have_align = 1
249 elif elem == 1: # sign
250 s += random.choice('+- ')
251 elif elem == 2 and not have_align: # zeropad
252 s += '0'
253 elif elem == 3: # width
254 s += str(random.randrange(1, 100))
255 elif elem == 4: # thousands separator
256 s += ','
257 elif elem == 5: # prec
258 s += '.'
259 s += str(random.randrange(100))
260 elif elem == 6:
261 if 4 in active: c = typespec.replace('n', '')
262 else: c = typespec
263 s += random.choice(c)
264 return s
265
266 # Partially brute force all possible format strings containing a thousands
267 # separator. Fall back to random where the runtime would become excessive.
268 # [[fill]align][sign][#][0][width][,][.precision][type]
269 def all_format_sep():
270 for align in ('', '<', '>', '=', '^'):
271 for fill in ('', 'x'):
272 if align == '': fill = ''
273 for sign in ('', '+', '-', ' '):
274 for zeropad in ('', '0'):
275 if align != '': zeropad = ''
276 for width in ['']+[str(y) for y in range(1, 15)]+['101']:
277 for prec in ['']+['.'+str(y) for y in range(15)]:
278 # for type in ('', 'E', 'e', 'G', 'g', 'F', 'f', '%' ):
279 type = random.choice(('', 'E', 'e', 'G', 'g', 'F', ' f', '%'))
280 yield ''.join((fill, align, sign, zeropad, width, ', ', prec, type))
281
282 # Partially brute force all possible format strings with an 'n' specifier.
283 # [[fill]align][sign][#][0][width][,][.precision][type]
284 def all_format_loc():
285 for align in ('', '<', '>', '=', '^'):
286 for fill in ('', 'x'):
287 if align == '': fill = ''
288 for sign in ('', '+', '-', ' '):
289 for zeropad in ('', '0'):
290 if align != '': zeropad = ''
291 for width in ['']+[str(y) for y in range(1, 20)]+['101']:
292 for prec in ['']+['.'+str(y) for y in range(1, 20)]:
293 yield ''.join((fill, align, sign, zeropad, width, pr ec, 'n'))
294
295 # Generate random format strings with a unicode fill character
296 # [[fill]align][sign][#][0][width][,][.precision][type]
297 def randfill(fill):
298 active = sorted(random.sample(range(5), random.randrange(6)))
299 s = ''
300 s += str(fill)
301 s += random.choice('<>=^')
302 for elem in active:
303 if elem == 0: # sign
304 s += random.choice('+- ')
305 elif elem == 1: # width
306 s += str(random.randrange(1, 100))
307 elif elem == 2: # thousands separator
308 s += ','
309 elif elem == 3: # prec
310 s += '.'
311 s += str(random.randrange(100))
312 elif elem == 4:
313 if 2 in active: c = 'EeGgFf%'
314 else: c = 'EeGgFfn%'
315 s += random.choice(c)
316 return s
317
318 # Generate random format strings with random locale setting
319 # [[fill]align][sign][#][0][width][,][.precision][type]
320 def rand_locale():
321 try:
322 loc = random.choice(locale_list)
323 locale.setlocale(locale.LC_ALL, loc)
324 except locale.Error as err:
325 pass
326 active = sorted(random.sample(range(5), random.randrange(6)))
327 s = ''
328 have_align = 0
329 for elem in active:
330 if elem == 0: # fill+align
331 s += chr(random.randrange(32, 128))
332 s += random.choice('<>=^')
333 have_align = 1
334 elif elem == 1: # sign
335 s += random.choice('+- ')
336 elif elem == 2 and not have_align: # zeropad
337 s += '0'
338 elif elem == 3: # width
339 s += str(random.randrange(1, 100))
340 elif elem == 4: # prec
341 s += '.'
342 s += str(random.randrange(100))
343 s += 'n'
344 return s
OLDNEW
« no previous file with comments | « Modules/_decimal/tests/deccheck.py ('k') | Modules/_decimal/tests/randdec.py » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+