ยปCore Development>Code coverage>Modules/_decimal/tests/formathelper.py

Python code coverage for Modules/_decimal/tests/formathelper.py

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