ยปCore Development>Code coverage>Lib/test/test_decimal.py

Python code coverage for Lib/test/test_decimal.py

#countcontent
1n/a# Copyright (c) 2004 Python Software Foundation.
2n/a# All rights reserved.
3n/a
4n/a# Written by Eric Price <eprice at tjhsst.edu>
5n/a# and Facundo Batista <facundo at taniquetil.com.ar>
6n/a# and Raymond Hettinger <python at rcn.com>
7n/a# and Aahz (aahz at pobox.com)
8n/a# and Tim Peters
9n/a
10n/a"""
11n/aThese are the test cases for the Decimal module.
12n/a
13n/aThere are two groups of tests, Arithmetic and Behaviour. The former test
14n/athe Decimal arithmetic using the tests provided by Mike Cowlishaw. The latter
15n/atest the pythonic behaviour according to PEP 327.
16n/a
17n/aCowlishaw's tests can be downloaded from:
18n/a
19n/a http://speleotrove.com/decimal/dectest.zip
20n/a
21n/aThis test module can be called from command line with one parameter (Arithmetic
22n/aor Behaviour) to test each part, or without parameter to test both parts. If
23n/ayou're working through IDLE, you can import this test module and call test_main()
24n/awith the corresponding argument.
25n/a"""
26n/a
27n/aimport math
28n/aimport os, sys
29n/aimport operator
30n/aimport warnings
31n/aimport pickle, copy
32n/aimport unittest
33n/aimport numbers
34n/aimport locale
35n/afrom test.support import (run_unittest, run_doctest, is_resource_enabled,
36n/a requires_IEEE_754, requires_docstrings)
37n/afrom test.support import (check_warnings, import_fresh_module, TestFailed,
38n/a run_with_locale, cpython_only)
39n/aimport random
40n/aimport inspect
41n/atry:
42n/a import threading
43n/aexcept ImportError:
44n/a threading = None
45n/a
46n/a
47n/aC = import_fresh_module('decimal', fresh=['_decimal'])
48n/aP = import_fresh_module('decimal', blocked=['_decimal'])
49n/aorig_sys_decimal = sys.modules['decimal']
50n/a
51n/a# fractions module must import the correct decimal module.
52n/acfractions = import_fresh_module('fractions', fresh=['fractions'])
53n/asys.modules['decimal'] = P
54n/apfractions = import_fresh_module('fractions', fresh=['fractions'])
55n/asys.modules['decimal'] = C
56n/afractions = {C:cfractions, P:pfractions}
57n/asys.modules['decimal'] = orig_sys_decimal
58n/a
59n/a
60n/a# Useful Test Constant
61n/aSignals = {
62n/a C: tuple(C.getcontext().flags.keys()) if C else None,
63n/a P: tuple(P.getcontext().flags.keys())
64n/a}
65n/a# Signals ordered with respect to precedence: when an operation
66n/a# produces multiple signals, signals occurring later in the list
67n/a# should be handled before those occurring earlier in the list.
68n/aOrderedSignals = {
69n/a C: [C.Clamped, C.Rounded, C.Inexact, C.Subnormal, C.Underflow,
70n/a C.Overflow, C.DivisionByZero, C.InvalidOperation,
71n/a C.FloatOperation] if C else None,
72n/a P: [P.Clamped, P.Rounded, P.Inexact, P.Subnormal, P.Underflow,
73n/a P.Overflow, P.DivisionByZero, P.InvalidOperation,
74n/a P.FloatOperation]
75n/a}
76n/adef assert_signals(cls, context, attr, expected):
77n/a d = getattr(context, attr)
78n/a cls.assertTrue(all(d[s] if s in expected else not d[s] for s in d))
79n/a
80n/aROUND_UP = P.ROUND_UP
81n/aROUND_DOWN = P.ROUND_DOWN
82n/aROUND_CEILING = P.ROUND_CEILING
83n/aROUND_FLOOR = P.ROUND_FLOOR
84n/aROUND_HALF_UP = P.ROUND_HALF_UP
85n/aROUND_HALF_DOWN = P.ROUND_HALF_DOWN
86n/aROUND_HALF_EVEN = P.ROUND_HALF_EVEN
87n/aROUND_05UP = P.ROUND_05UP
88n/a
89n/aRoundingModes = [
90n/a ROUND_UP, ROUND_DOWN, ROUND_CEILING, ROUND_FLOOR,
91n/a ROUND_HALF_UP, ROUND_HALF_DOWN, ROUND_HALF_EVEN,
92n/a ROUND_05UP
93n/a]
94n/a
95n/a# Tests are built around these assumed context defaults.
96n/a# test_main() restores the original context.
97n/aORIGINAL_CONTEXT = {
98n/a C: C.getcontext().copy() if C else None,
99n/a P: P.getcontext().copy()
100n/a}
101n/adef init(m):
102n/a if not m: return
103n/a DefaultTestContext = m.Context(
104n/a prec=9, rounding=ROUND_HALF_EVEN, traps=dict.fromkeys(Signals[m], 0)
105n/a )
106n/a m.setcontext(DefaultTestContext)
107n/a
108n/aTESTDATADIR = 'decimaltestdata'
109n/aif __name__ == '__main__':
110n/a file = sys.argv[0]
111n/aelse:
112n/a file = __file__
113n/atestdir = os.path.dirname(file) or os.curdir
114n/adirectory = testdir + os.sep + TESTDATADIR + os.sep
115n/a
116n/askip_expected = not os.path.isdir(directory)
117n/a
118n/a# Make sure it actually raises errors when not expected and caught in flags
119n/a# Slower, since it runs some things several times.
120n/aEXTENDEDERRORTEST = False
121n/a
122n/a# Test extra functionality in the C version (-DEXTRA_FUNCTIONALITY).
123n/aEXTRA_FUNCTIONALITY = True if hasattr(C, 'DecClamped') else False
124n/arequires_extra_functionality = unittest.skipUnless(
125n/a EXTRA_FUNCTIONALITY, "test requires build with -DEXTRA_FUNCTIONALITY")
126n/askip_if_extra_functionality = unittest.skipIf(
127n/a EXTRA_FUNCTIONALITY, "test requires regular build")
128n/a
129n/a
130n/aclass IBMTestCases(unittest.TestCase):
131n/a """Class which tests the Decimal class against the IBM test cases."""
132n/a
133n/a def setUp(self):
134n/a self.context = self.decimal.Context()
135n/a self.readcontext = self.decimal.Context()
136n/a self.ignore_list = ['#']
137n/a
138n/a # List of individual .decTest test ids that correspond to tests that
139n/a # we're skipping for one reason or another.
140n/a self.skipped_test_ids = set([
141n/a # Skip implementation-specific scaleb tests.
142n/a 'scbx164',
143n/a 'scbx165',
144n/a
145n/a # For some operations (currently exp, ln, log10, power), the decNumber
146n/a # reference implementation imposes additional restrictions on the context
147n/a # and operands. These restrictions are not part of the specification;
148n/a # however, the effect of these restrictions does show up in some of the
149n/a # testcases. We skip testcases that violate these restrictions, since
150n/a # Decimal behaves differently from decNumber for these testcases so these
151n/a # testcases would otherwise fail.
152n/a 'expx901',
153n/a 'expx902',
154n/a 'expx903',
155n/a 'expx905',
156n/a 'lnx901',
157n/a 'lnx902',
158n/a 'lnx903',
159n/a 'lnx905',
160n/a 'logx901',
161n/a 'logx902',
162n/a 'logx903',
163n/a 'logx905',
164n/a 'powx1183',
165n/a 'powx1184',
166n/a 'powx4001',
167n/a 'powx4002',
168n/a 'powx4003',
169n/a 'powx4005',
170n/a 'powx4008',
171n/a 'powx4010',
172n/a 'powx4012',
173n/a 'powx4014',
174n/a ])
175n/a
176n/a if self.decimal == C:
177n/a # status has additional Subnormal, Underflow
178n/a self.skipped_test_ids.add('pwsx803')
179n/a self.skipped_test_ids.add('pwsx805')
180n/a # Correct rounding (skipped for decNumber, too)
181n/a self.skipped_test_ids.add('powx4302')
182n/a self.skipped_test_ids.add('powx4303')
183n/a self.skipped_test_ids.add('powx4342')
184n/a self.skipped_test_ids.add('powx4343')
185n/a # http://bugs.python.org/issue7049
186n/a self.skipped_test_ids.add('pwmx325')
187n/a self.skipped_test_ids.add('pwmx326')
188n/a
189n/a # Map test directives to setter functions.
190n/a self.ChangeDict = {'precision' : self.change_precision,
191n/a 'rounding' : self.change_rounding_method,
192n/a 'maxexponent' : self.change_max_exponent,
193n/a 'minexponent' : self.change_min_exponent,
194n/a 'clamp' : self.change_clamp}
195n/a
196n/a # Name adapter to be able to change the Decimal and Context
197n/a # interface without changing the test files from Cowlishaw.
198n/a self.NameAdapter = {'and':'logical_and',
199n/a 'apply':'_apply',
200n/a 'class':'number_class',
201n/a 'comparesig':'compare_signal',
202n/a 'comparetotal':'compare_total',
203n/a 'comparetotmag':'compare_total_mag',
204n/a 'copy':'copy_decimal',
205n/a 'copyabs':'copy_abs',
206n/a 'copynegate':'copy_negate',
207n/a 'copysign':'copy_sign',
208n/a 'divideint':'divide_int',
209n/a 'invert':'logical_invert',
210n/a 'iscanonical':'is_canonical',
211n/a 'isfinite':'is_finite',
212n/a 'isinfinite':'is_infinite',
213n/a 'isnan':'is_nan',
214n/a 'isnormal':'is_normal',
215n/a 'isqnan':'is_qnan',
216n/a 'issigned':'is_signed',
217n/a 'issnan':'is_snan',
218n/a 'issubnormal':'is_subnormal',
219n/a 'iszero':'is_zero',
220n/a 'maxmag':'max_mag',
221n/a 'minmag':'min_mag',
222n/a 'nextminus':'next_minus',
223n/a 'nextplus':'next_plus',
224n/a 'nexttoward':'next_toward',
225n/a 'or':'logical_or',
226n/a 'reduce':'normalize',
227n/a 'remaindernear':'remainder_near',
228n/a 'samequantum':'same_quantum',
229n/a 'squareroot':'sqrt',
230n/a 'toeng':'to_eng_string',
231n/a 'tointegral':'to_integral_value',
232n/a 'tointegralx':'to_integral_exact',
233n/a 'tosci':'to_sci_string',
234n/a 'xor':'logical_xor'}
235n/a
236n/a # Map test-case names to roundings.
237n/a self.RoundingDict = {'ceiling' : ROUND_CEILING,
238n/a 'down' : ROUND_DOWN,
239n/a 'floor' : ROUND_FLOOR,
240n/a 'half_down' : ROUND_HALF_DOWN,
241n/a 'half_even' : ROUND_HALF_EVEN,
242n/a 'half_up' : ROUND_HALF_UP,
243n/a 'up' : ROUND_UP,
244n/a '05up' : ROUND_05UP}
245n/a
246n/a # Map the test cases' error names to the actual errors.
247n/a self.ErrorNames = {'clamped' : self.decimal.Clamped,
248n/a 'conversion_syntax' : self.decimal.InvalidOperation,
249n/a 'division_by_zero' : self.decimal.DivisionByZero,
250n/a 'division_impossible' : self.decimal.InvalidOperation,
251n/a 'division_undefined' : self.decimal.InvalidOperation,
252n/a 'inexact' : self.decimal.Inexact,
253n/a 'invalid_context' : self.decimal.InvalidOperation,
254n/a 'invalid_operation' : self.decimal.InvalidOperation,
255n/a 'overflow' : self.decimal.Overflow,
256n/a 'rounded' : self.decimal.Rounded,
257n/a 'subnormal' : self.decimal.Subnormal,
258n/a 'underflow' : self.decimal.Underflow}
259n/a
260n/a # The following functions return True/False rather than a
261n/a # Decimal instance.
262n/a self.LogicalFunctions = ('is_canonical',
263n/a 'is_finite',
264n/a 'is_infinite',
265n/a 'is_nan',
266n/a 'is_normal',
267n/a 'is_qnan',
268n/a 'is_signed',
269n/a 'is_snan',
270n/a 'is_subnormal',
271n/a 'is_zero',
272n/a 'same_quantum')
273n/a
274n/a def read_unlimited(self, v, context):
275n/a """Work around the limitations of the 32-bit _decimal version. The
276n/a guaranteed maximum values for prec, Emax etc. are 425000000,
277n/a but higher values usually work, except for rare corner cases.
278n/a In particular, all of the IBM tests pass with maximum values
279n/a of 1070000000."""
280n/a if self.decimal == C and self.decimal.MAX_EMAX == 425000000:
281n/a self.readcontext._unsafe_setprec(1070000000)
282n/a self.readcontext._unsafe_setemax(1070000000)
283n/a self.readcontext._unsafe_setemin(-1070000000)
284n/a return self.readcontext.create_decimal(v)
285n/a else:
286n/a return self.decimal.Decimal(v, context)
287n/a
288n/a def eval_file(self, file):
289n/a global skip_expected
290n/a if skip_expected:
291n/a raise unittest.SkipTest
292n/a with open(file) as f:
293n/a for line in f:
294n/a line = line.replace('\r\n', '').replace('\n', '')
295n/a #print line
296n/a try:
297n/a t = self.eval_line(line)
298n/a except self.decimal.DecimalException as exception:
299n/a #Exception raised where there shouldn't have been one.
300n/a self.fail('Exception "'+exception.__class__.__name__ + '" raised on line '+line)
301n/a
302n/a
303n/a def eval_line(self, s):
304n/a if s.find(' -> ') >= 0 and s[:2] != '--' and not s.startswith(' --'):
305n/a s = (s.split('->')[0] + '->' +
306n/a s.split('->')[1].split('--')[0]).strip()
307n/a else:
308n/a s = s.split('--')[0].strip()
309n/a
310n/a for ignore in self.ignore_list:
311n/a if s.find(ignore) >= 0:
312n/a #print s.split()[0], 'NotImplemented--', ignore
313n/a return
314n/a if not s:
315n/a return
316n/a elif ':' in s:
317n/a return self.eval_directive(s)
318n/a else:
319n/a return self.eval_equation(s)
320n/a
321n/a def eval_directive(self, s):
322n/a funct, value = (x.strip().lower() for x in s.split(':'))
323n/a if funct == 'rounding':
324n/a value = self.RoundingDict[value]
325n/a else:
326n/a try:
327n/a value = int(value)
328n/a except ValueError:
329n/a pass
330n/a
331n/a funct = self.ChangeDict.get(funct, (lambda *args: None))
332n/a funct(value)
333n/a
334n/a def eval_equation(self, s):
335n/a
336n/a if not TEST_ALL and random.random() < 0.90:
337n/a return
338n/a
339n/a self.context.clear_flags()
340n/a
341n/a try:
342n/a Sides = s.split('->')
343n/a L = Sides[0].strip().split()
344n/a id = L[0]
345n/a if DEBUG:
346n/a print("Test ", id, end=" ")
347n/a funct = L[1].lower()
348n/a valstemp = L[2:]
349n/a L = Sides[1].strip().split()
350n/a ans = L[0]
351n/a exceptions = L[1:]
352n/a except (TypeError, AttributeError, IndexError):
353n/a raise self.decimal.InvalidOperation
354n/a def FixQuotes(val):
355n/a val = val.replace("''", 'SingleQuote').replace('""', 'DoubleQuote')
356n/a val = val.replace("'", '').replace('"', '')
357n/a val = val.replace('SingleQuote', "'").replace('DoubleQuote', '"')
358n/a return val
359n/a
360n/a if id in self.skipped_test_ids:
361n/a return
362n/a
363n/a fname = self.NameAdapter.get(funct, funct)
364n/a if fname == 'rescale':
365n/a return
366n/a funct = getattr(self.context, fname)
367n/a vals = []
368n/a conglomerate = ''
369n/a quote = 0
370n/a theirexceptions = [self.ErrorNames[x.lower()] for x in exceptions]
371n/a
372n/a for exception in Signals[self.decimal]:
373n/a self.context.traps[exception] = 1 #Catch these bugs...
374n/a for exception in theirexceptions:
375n/a self.context.traps[exception] = 0
376n/a for i, val in enumerate(valstemp):
377n/a if val.count("'") % 2 == 1:
378n/a quote = 1 - quote
379n/a if quote:
380n/a conglomerate = conglomerate + ' ' + val
381n/a continue
382n/a else:
383n/a val = conglomerate + val
384n/a conglomerate = ''
385n/a v = FixQuotes(val)
386n/a if fname in ('to_sci_string', 'to_eng_string'):
387n/a if EXTENDEDERRORTEST:
388n/a for error in theirexceptions:
389n/a self.context.traps[error] = 1
390n/a try:
391n/a funct(self.context.create_decimal(v))
392n/a except error:
393n/a pass
394n/a except Signals[self.decimal] as e:
395n/a self.fail("Raised %s in %s when %s disabled" % \
396n/a (e, s, error))
397n/a else:
398n/a self.fail("Did not raise %s in %s" % (error, s))
399n/a self.context.traps[error] = 0
400n/a v = self.context.create_decimal(v)
401n/a else:
402n/a v = self.read_unlimited(v, self.context)
403n/a vals.append(v)
404n/a
405n/a ans = FixQuotes(ans)
406n/a
407n/a if EXTENDEDERRORTEST and fname not in ('to_sci_string', 'to_eng_string'):
408n/a for error in theirexceptions:
409n/a self.context.traps[error] = 1
410n/a try:
411n/a funct(*vals)
412n/a except error:
413n/a pass
414n/a except Signals[self.decimal] as e:
415n/a self.fail("Raised %s in %s when %s disabled" % \
416n/a (e, s, error))
417n/a else:
418n/a self.fail("Did not raise %s in %s" % (error, s))
419n/a self.context.traps[error] = 0
420n/a
421n/a # as above, but add traps cumulatively, to check precedence
422n/a ordered_errors = [e for e in OrderedSignals[self.decimal] if e in theirexceptions]
423n/a for error in ordered_errors:
424n/a self.context.traps[error] = 1
425n/a try:
426n/a funct(*vals)
427n/a except error:
428n/a pass
429n/a except Signals[self.decimal] as e:
430n/a self.fail("Raised %s in %s; expected %s" %
431n/a (type(e), s, error))
432n/a else:
433n/a self.fail("Did not raise %s in %s" % (error, s))
434n/a # reset traps
435n/a for error in ordered_errors:
436n/a self.context.traps[error] = 0
437n/a
438n/a
439n/a if DEBUG:
440n/a print("--", self.context)
441n/a try:
442n/a result = str(funct(*vals))
443n/a if fname in self.LogicalFunctions:
444n/a result = str(int(eval(result))) # 'True', 'False' -> '1', '0'
445n/a except Signals[self.decimal] as error:
446n/a self.fail("Raised %s in %s" % (error, s))
447n/a except: #Catch any error long enough to state the test case.
448n/a print("ERROR:", s)
449n/a raise
450n/a
451n/a myexceptions = self.getexceptions()
452n/a
453n/a myexceptions.sort(key=repr)
454n/a theirexceptions.sort(key=repr)
455n/a
456n/a self.assertEqual(result, ans,
457n/a 'Incorrect answer for ' + s + ' -- got ' + result)
458n/a
459n/a self.assertEqual(myexceptions, theirexceptions,
460n/a 'Incorrect flags set in ' + s + ' -- got ' + str(myexceptions))
461n/a
462n/a def getexceptions(self):
463n/a return [e for e in Signals[self.decimal] if self.context.flags[e]]
464n/a
465n/a def change_precision(self, prec):
466n/a if self.decimal == C and self.decimal.MAX_PREC == 425000000:
467n/a self.context._unsafe_setprec(prec)
468n/a else:
469n/a self.context.prec = prec
470n/a def change_rounding_method(self, rounding):
471n/a self.context.rounding = rounding
472n/a def change_min_exponent(self, exp):
473n/a if self.decimal == C and self.decimal.MAX_PREC == 425000000:
474n/a self.context._unsafe_setemin(exp)
475n/a else:
476n/a self.context.Emin = exp
477n/a def change_max_exponent(self, exp):
478n/a if self.decimal == C and self.decimal.MAX_PREC == 425000000:
479n/a self.context._unsafe_setemax(exp)
480n/a else:
481n/a self.context.Emax = exp
482n/a def change_clamp(self, clamp):
483n/a self.context.clamp = clamp
484n/a
485n/aclass CIBMTestCases(IBMTestCases):
486n/a decimal = C
487n/aclass PyIBMTestCases(IBMTestCases):
488n/a decimal = P
489n/a
490n/a# The following classes test the behaviour of Decimal according to PEP 327
491n/a
492n/aclass ExplicitConstructionTest(unittest.TestCase):
493n/a '''Unit tests for Explicit Construction cases of Decimal.'''
494n/a
495n/a def test_explicit_empty(self):
496n/a Decimal = self.decimal.Decimal
497n/a self.assertEqual(Decimal(), Decimal("0"))
498n/a
499n/a def test_explicit_from_None(self):
500n/a Decimal = self.decimal.Decimal
501n/a self.assertRaises(TypeError, Decimal, None)
502n/a
503n/a def test_explicit_from_int(self):
504n/a Decimal = self.decimal.Decimal
505n/a
506n/a #positive
507n/a d = Decimal(45)
508n/a self.assertEqual(str(d), '45')
509n/a
510n/a #very large positive
511n/a d = Decimal(500000123)
512n/a self.assertEqual(str(d), '500000123')
513n/a
514n/a #negative
515n/a d = Decimal(-45)
516n/a self.assertEqual(str(d), '-45')
517n/a
518n/a #zero
519n/a d = Decimal(0)
520n/a self.assertEqual(str(d), '0')
521n/a
522n/a # single word longs
523n/a for n in range(0, 32):
524n/a for sign in (-1, 1):
525n/a for x in range(-5, 5):
526n/a i = sign * (2**n + x)
527n/a d = Decimal(i)
528n/a self.assertEqual(str(d), str(i))
529n/a
530n/a def test_explicit_from_string(self):
531n/a Decimal = self.decimal.Decimal
532n/a InvalidOperation = self.decimal.InvalidOperation
533n/a localcontext = self.decimal.localcontext
534n/a
535n/a #empty
536n/a self.assertEqual(str(Decimal('')), 'NaN')
537n/a
538n/a #int
539n/a self.assertEqual(str(Decimal('45')), '45')
540n/a
541n/a #float
542n/a self.assertEqual(str(Decimal('45.34')), '45.34')
543n/a
544n/a #engineer notation
545n/a self.assertEqual(str(Decimal('45e2')), '4.5E+3')
546n/a
547n/a #just not a number
548n/a self.assertEqual(str(Decimal('ugly')), 'NaN')
549n/a
550n/a #leading and trailing whitespace permitted
551n/a self.assertEqual(str(Decimal('1.3E4 \n')), '1.3E+4')
552n/a self.assertEqual(str(Decimal(' -7.89')), '-7.89')
553n/a self.assertEqual(str(Decimal(" 3.45679 ")), '3.45679')
554n/a
555n/a # underscores
556n/a self.assertEqual(str(Decimal('1_3.3e4_0')), '1.33E+41')
557n/a self.assertEqual(str(Decimal('1_0_0_0')), '1000')
558n/a
559n/a # unicode whitespace
560n/a for lead in ["", ' ', '\u00a0', '\u205f']:
561n/a for trail in ["", ' ', '\u00a0', '\u205f']:
562n/a self.assertEqual(str(Decimal(lead + '9.311E+28' + trail)),
563n/a '9.311E+28')
564n/a
565n/a with localcontext() as c:
566n/a c.traps[InvalidOperation] = True
567n/a # Invalid string
568n/a self.assertRaises(InvalidOperation, Decimal, "xyz")
569n/a # Two arguments max
570n/a self.assertRaises(TypeError, Decimal, "1234", "x", "y")
571n/a
572n/a # space within the numeric part
573n/a self.assertRaises(InvalidOperation, Decimal, "1\u00a02\u00a03")
574n/a self.assertRaises(InvalidOperation, Decimal, "\u00a01\u00a02\u00a0")
575n/a
576n/a # unicode whitespace
577n/a self.assertRaises(InvalidOperation, Decimal, "\u00a0")
578n/a self.assertRaises(InvalidOperation, Decimal, "\u00a0\u00a0")
579n/a
580n/a # embedded NUL
581n/a self.assertRaises(InvalidOperation, Decimal, "12\u00003")
582n/a
583n/a # underscores don't prevent errors
584n/a self.assertRaises(InvalidOperation, Decimal, "1_2_\u00003")
585n/a
586n/a @cpython_only
587n/a def test_from_legacy_strings(self):
588n/a import _testcapi
589n/a Decimal = self.decimal.Decimal
590n/a context = self.decimal.Context()
591n/a
592n/a s = _testcapi.unicode_legacy_string('9.999999')
593n/a self.assertEqual(str(Decimal(s)), '9.999999')
594n/a self.assertEqual(str(context.create_decimal(s)), '9.999999')
595n/a
596n/a def test_explicit_from_tuples(self):
597n/a Decimal = self.decimal.Decimal
598n/a
599n/a #zero
600n/a d = Decimal( (0, (0,), 0) )
601n/a self.assertEqual(str(d), '0')
602n/a
603n/a #int
604n/a d = Decimal( (1, (4, 5), 0) )
605n/a self.assertEqual(str(d), '-45')
606n/a
607n/a #float
608n/a d = Decimal( (0, (4, 5, 3, 4), -2) )
609n/a self.assertEqual(str(d), '45.34')
610n/a
611n/a #weird
612n/a d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
613n/a self.assertEqual(str(d), '-4.34913534E-17')
614n/a
615n/a #inf
616n/a d = Decimal( (0, (), "F") )
617n/a self.assertEqual(str(d), 'Infinity')
618n/a
619n/a #wrong number of items
620n/a self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1)) )
621n/a
622n/a #bad sign
623n/a self.assertRaises(ValueError, Decimal, (8, (4, 3, 4, 9, 1), 2) )
624n/a self.assertRaises(ValueError, Decimal, (0., (4, 3, 4, 9, 1), 2) )
625n/a self.assertRaises(ValueError, Decimal, (Decimal(1), (4, 3, 4, 9, 1), 2))
626n/a
627n/a #bad exp
628n/a self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), 'wrong!') )
629n/a self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), 0.) )
630n/a self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), '1') )
631n/a
632n/a #bad coefficients
633n/a self.assertRaises(ValueError, Decimal, (1, "xyz", 2) )
634n/a self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, None, 1), 2) )
635n/a self.assertRaises(ValueError, Decimal, (1, (4, -3, 4, 9, 1), 2) )
636n/a self.assertRaises(ValueError, Decimal, (1, (4, 10, 4, 9, 1), 2) )
637n/a self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 'a', 1), 2) )
638n/a
639n/a def test_explicit_from_list(self):
640n/a Decimal = self.decimal.Decimal
641n/a
642n/a d = Decimal([0, [0], 0])
643n/a self.assertEqual(str(d), '0')
644n/a
645n/a d = Decimal([1, [4, 3, 4, 9, 1, 3, 5, 3, 4], -25])
646n/a self.assertEqual(str(d), '-4.34913534E-17')
647n/a
648n/a d = Decimal([1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25])
649n/a self.assertEqual(str(d), '-4.34913534E-17')
650n/a
651n/a d = Decimal((1, [4, 3, 4, 9, 1, 3, 5, 3, 4], -25))
652n/a self.assertEqual(str(d), '-4.34913534E-17')
653n/a
654n/a def test_explicit_from_bool(self):
655n/a Decimal = self.decimal.Decimal
656n/a
657n/a self.assertIs(bool(Decimal(0)), False)
658n/a self.assertIs(bool(Decimal(1)), True)
659n/a self.assertEqual(Decimal(False), Decimal(0))
660n/a self.assertEqual(Decimal(True), Decimal(1))
661n/a
662n/a def test_explicit_from_Decimal(self):
663n/a Decimal = self.decimal.Decimal
664n/a
665n/a #positive
666n/a d = Decimal(45)
667n/a e = Decimal(d)
668n/a self.assertEqual(str(e), '45')
669n/a
670n/a #very large positive
671n/a d = Decimal(500000123)
672n/a e = Decimal(d)
673n/a self.assertEqual(str(e), '500000123')
674n/a
675n/a #negative
676n/a d = Decimal(-45)
677n/a e = Decimal(d)
678n/a self.assertEqual(str(e), '-45')
679n/a
680n/a #zero
681n/a d = Decimal(0)
682n/a e = Decimal(d)
683n/a self.assertEqual(str(e), '0')
684n/a
685n/a @requires_IEEE_754
686n/a def test_explicit_from_float(self):
687n/a
688n/a Decimal = self.decimal.Decimal
689n/a
690n/a r = Decimal(0.1)
691n/a self.assertEqual(type(r), Decimal)
692n/a self.assertEqual(str(r),
693n/a '0.1000000000000000055511151231257827021181583404541015625')
694n/a self.assertTrue(Decimal(float('nan')).is_qnan())
695n/a self.assertTrue(Decimal(float('inf')).is_infinite())
696n/a self.assertTrue(Decimal(float('-inf')).is_infinite())
697n/a self.assertEqual(str(Decimal(float('nan'))),
698n/a str(Decimal('NaN')))
699n/a self.assertEqual(str(Decimal(float('inf'))),
700n/a str(Decimal('Infinity')))
701n/a self.assertEqual(str(Decimal(float('-inf'))),
702n/a str(Decimal('-Infinity')))
703n/a self.assertEqual(str(Decimal(float('-0.0'))),
704n/a str(Decimal('-0')))
705n/a for i in range(200):
706n/a x = random.expovariate(0.01) * (random.random() * 2.0 - 1.0)
707n/a self.assertEqual(x, float(Decimal(x))) # roundtrip
708n/a
709n/a def test_explicit_context_create_decimal(self):
710n/a Decimal = self.decimal.Decimal
711n/a InvalidOperation = self.decimal.InvalidOperation
712n/a Rounded = self.decimal.Rounded
713n/a
714n/a nc = copy.copy(self.decimal.getcontext())
715n/a nc.prec = 3
716n/a
717n/a # empty
718n/a d = Decimal()
719n/a self.assertEqual(str(d), '0')
720n/a d = nc.create_decimal()
721n/a self.assertEqual(str(d), '0')
722n/a
723n/a # from None
724n/a self.assertRaises(TypeError, nc.create_decimal, None)
725n/a
726n/a # from int
727n/a d = nc.create_decimal(456)
728n/a self.assertIsInstance(d, Decimal)
729n/a self.assertEqual(nc.create_decimal(45678),
730n/a nc.create_decimal('457E+2'))
731n/a
732n/a # from string
733n/a d = Decimal('456789')
734n/a self.assertEqual(str(d), '456789')
735n/a d = nc.create_decimal('456789')
736n/a self.assertEqual(str(d), '4.57E+5')
737n/a # leading and trailing whitespace should result in a NaN;
738n/a # spaces are already checked in Cowlishaw's test-suite, so
739n/a # here we just check that a trailing newline results in a NaN
740n/a self.assertEqual(str(nc.create_decimal('3.14\n')), 'NaN')
741n/a
742n/a # from tuples
743n/a d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
744n/a self.assertEqual(str(d), '-4.34913534E-17')
745n/a d = nc.create_decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
746n/a self.assertEqual(str(d), '-4.35E-17')
747n/a
748n/a # from Decimal
749n/a prevdec = Decimal(500000123)
750n/a d = Decimal(prevdec)
751n/a self.assertEqual(str(d), '500000123')
752n/a d = nc.create_decimal(prevdec)
753n/a self.assertEqual(str(d), '5.00E+8')
754n/a
755n/a # more integers
756n/a nc.prec = 28
757n/a nc.traps[InvalidOperation] = True
758n/a
759n/a for v in [-2**63-1, -2**63, -2**31-1, -2**31, 0,
760n/a 2**31-1, 2**31, 2**63-1, 2**63]:
761n/a d = nc.create_decimal(v)
762n/a self.assertTrue(isinstance(d, Decimal))
763n/a self.assertEqual(int(d), v)
764n/a
765n/a nc.prec = 3
766n/a nc.traps[Rounded] = True
767n/a self.assertRaises(Rounded, nc.create_decimal, 1234)
768n/a
769n/a # from string
770n/a nc.prec = 28
771n/a self.assertEqual(str(nc.create_decimal('0E-017')), '0E-17')
772n/a self.assertEqual(str(nc.create_decimal('45')), '45')
773n/a self.assertEqual(str(nc.create_decimal('-Inf')), '-Infinity')
774n/a self.assertEqual(str(nc.create_decimal('NaN123')), 'NaN123')
775n/a
776n/a # invalid arguments
777n/a self.assertRaises(InvalidOperation, nc.create_decimal, "xyz")
778n/a self.assertRaises(ValueError, nc.create_decimal, (1, "xyz", -25))
779n/a self.assertRaises(TypeError, nc.create_decimal, "1234", "5678")
780n/a # no whitespace and underscore stripping is done with this method
781n/a self.assertRaises(InvalidOperation, nc.create_decimal, " 1234")
782n/a self.assertRaises(InvalidOperation, nc.create_decimal, "12_34")
783n/a
784n/a # too many NaN payload digits
785n/a nc.prec = 3
786n/a self.assertRaises(InvalidOperation, nc.create_decimal, 'NaN12345')
787n/a self.assertRaises(InvalidOperation, nc.create_decimal,
788n/a Decimal('NaN12345'))
789n/a
790n/a nc.traps[InvalidOperation] = False
791n/a self.assertEqual(str(nc.create_decimal('NaN12345')), 'NaN')
792n/a self.assertTrue(nc.flags[InvalidOperation])
793n/a
794n/a nc.flags[InvalidOperation] = False
795n/a self.assertEqual(str(nc.create_decimal(Decimal('NaN12345'))), 'NaN')
796n/a self.assertTrue(nc.flags[InvalidOperation])
797n/a
798n/a def test_explicit_context_create_from_float(self):
799n/a
800n/a Decimal = self.decimal.Decimal
801n/a
802n/a nc = self.decimal.Context()
803n/a r = nc.create_decimal(0.1)
804n/a self.assertEqual(type(r), Decimal)
805n/a self.assertEqual(str(r), '0.1000000000000000055511151231')
806n/a self.assertTrue(nc.create_decimal(float('nan')).is_qnan())
807n/a self.assertTrue(nc.create_decimal(float('inf')).is_infinite())
808n/a self.assertTrue(nc.create_decimal(float('-inf')).is_infinite())
809n/a self.assertEqual(str(nc.create_decimal(float('nan'))),
810n/a str(nc.create_decimal('NaN')))
811n/a self.assertEqual(str(nc.create_decimal(float('inf'))),
812n/a str(nc.create_decimal('Infinity')))
813n/a self.assertEqual(str(nc.create_decimal(float('-inf'))),
814n/a str(nc.create_decimal('-Infinity')))
815n/a self.assertEqual(str(nc.create_decimal(float('-0.0'))),
816n/a str(nc.create_decimal('-0')))
817n/a nc.prec = 100
818n/a for i in range(200):
819n/a x = random.expovariate(0.01) * (random.random() * 2.0 - 1.0)
820n/a self.assertEqual(x, float(nc.create_decimal(x))) # roundtrip
821n/a
822n/a def test_unicode_digits(self):
823n/a Decimal = self.decimal.Decimal
824n/a
825n/a test_values = {
826n/a '\uff11': '1',
827n/a '\u0660.\u0660\u0663\u0667\u0662e-\u0663' : '0.0000372',
828n/a '-nan\u0c68\u0c6a\u0c66\u0c66' : '-NaN2400',
829n/a }
830n/a for input, expected in test_values.items():
831n/a self.assertEqual(str(Decimal(input)), expected)
832n/a
833n/aclass CExplicitConstructionTest(ExplicitConstructionTest):
834n/a decimal = C
835n/aclass PyExplicitConstructionTest(ExplicitConstructionTest):
836n/a decimal = P
837n/a
838n/aclass ImplicitConstructionTest(unittest.TestCase):
839n/a '''Unit tests for Implicit Construction cases of Decimal.'''
840n/a
841n/a def test_implicit_from_None(self):
842n/a Decimal = self.decimal.Decimal
843n/a self.assertRaises(TypeError, eval, 'Decimal(5) + None', locals())
844n/a
845n/a def test_implicit_from_int(self):
846n/a Decimal = self.decimal.Decimal
847n/a
848n/a #normal
849n/a self.assertEqual(str(Decimal(5) + 45), '50')
850n/a #exceeding precision
851n/a self.assertEqual(Decimal(5) + 123456789000, Decimal(123456789000))
852n/a
853n/a def test_implicit_from_string(self):
854n/a Decimal = self.decimal.Decimal
855n/a self.assertRaises(TypeError, eval, 'Decimal(5) + "3"', locals())
856n/a
857n/a def test_implicit_from_float(self):
858n/a Decimal = self.decimal.Decimal
859n/a self.assertRaises(TypeError, eval, 'Decimal(5) + 2.2', locals())
860n/a
861n/a def test_implicit_from_Decimal(self):
862n/a Decimal = self.decimal.Decimal
863n/a self.assertEqual(Decimal(5) + Decimal(45), Decimal(50))
864n/a
865n/a def test_rop(self):
866n/a Decimal = self.decimal.Decimal
867n/a
868n/a # Allow other classes to be trained to interact with Decimals
869n/a class E:
870n/a def __divmod__(self, other):
871n/a return 'divmod ' + str(other)
872n/a def __rdivmod__(self, other):
873n/a return str(other) + ' rdivmod'
874n/a def __lt__(self, other):
875n/a return 'lt ' + str(other)
876n/a def __gt__(self, other):
877n/a return 'gt ' + str(other)
878n/a def __le__(self, other):
879n/a return 'le ' + str(other)
880n/a def __ge__(self, other):
881n/a return 'ge ' + str(other)
882n/a def __eq__(self, other):
883n/a return 'eq ' + str(other)
884n/a def __ne__(self, other):
885n/a return 'ne ' + str(other)
886n/a
887n/a self.assertEqual(divmod(E(), Decimal(10)), 'divmod 10')
888n/a self.assertEqual(divmod(Decimal(10), E()), '10 rdivmod')
889n/a self.assertEqual(eval('Decimal(10) < E()'), 'gt 10')
890n/a self.assertEqual(eval('Decimal(10) > E()'), 'lt 10')
891n/a self.assertEqual(eval('Decimal(10) <= E()'), 'ge 10')
892n/a self.assertEqual(eval('Decimal(10) >= E()'), 'le 10')
893n/a self.assertEqual(eval('Decimal(10) == E()'), 'eq 10')
894n/a self.assertEqual(eval('Decimal(10) != E()'), 'ne 10')
895n/a
896n/a # insert operator methods and then exercise them
897n/a oplist = [
898n/a ('+', '__add__', '__radd__'),
899n/a ('-', '__sub__', '__rsub__'),
900n/a ('*', '__mul__', '__rmul__'),
901n/a ('/', '__truediv__', '__rtruediv__'),
902n/a ('%', '__mod__', '__rmod__'),
903n/a ('//', '__floordiv__', '__rfloordiv__'),
904n/a ('**', '__pow__', '__rpow__')
905n/a ]
906n/a
907n/a for sym, lop, rop in oplist:
908n/a setattr(E, lop, lambda self, other: 'str' + lop + str(other))
909n/a setattr(E, rop, lambda self, other: str(other) + rop + 'str')
910n/a self.assertEqual(eval('E()' + sym + 'Decimal(10)'),
911n/a 'str' + lop + '10')
912n/a self.assertEqual(eval('Decimal(10)' + sym + 'E()'),
913n/a '10' + rop + 'str')
914n/a
915n/aclass CImplicitConstructionTest(ImplicitConstructionTest):
916n/a decimal = C
917n/aclass PyImplicitConstructionTest(ImplicitConstructionTest):
918n/a decimal = P
919n/a
920n/aclass FormatTest(unittest.TestCase):
921n/a '''Unit tests for the format function.'''
922n/a def test_formatting(self):
923n/a Decimal = self.decimal.Decimal
924n/a
925n/a # triples giving a format, a Decimal, and the expected result
926n/a test_values = [
927n/a ('e', '0E-15', '0e-15'),
928n/a ('e', '2.3E-15', '2.3e-15'),
929n/a ('e', '2.30E+2', '2.30e+2'), # preserve significant zeros
930n/a ('e', '2.30000E-15', '2.30000e-15'),
931n/a ('e', '1.23456789123456789e40', '1.23456789123456789e+40'),
932n/a ('e', '1.5', '1.5e+0'),
933n/a ('e', '0.15', '1.5e-1'),
934n/a ('e', '0.015', '1.5e-2'),
935n/a ('e', '0.0000000000015', '1.5e-12'),
936n/a ('e', '15.0', '1.50e+1'),
937n/a ('e', '-15', '-1.5e+1'),
938n/a ('e', '0', '0e+0'),
939n/a ('e', '0E1', '0e+1'),
940n/a ('e', '0.0', '0e-1'),
941n/a ('e', '0.00', '0e-2'),
942n/a ('.6e', '0E-15', '0.000000e-9'),
943n/a ('.6e', '0', '0.000000e+6'),
944n/a ('.6e', '9.999999', '9.999999e+0'),
945n/a ('.6e', '9.9999999', '1.000000e+1'),
946n/a ('.6e', '-1.23e5', '-1.230000e+5'),
947n/a ('.6e', '1.23456789e-3', '1.234568e-3'),
948n/a ('f', '0', '0'),
949n/a ('f', '0.0', '0.0'),
950n/a ('f', '0E-2', '0.00'),
951n/a ('f', '0.00E-8', '0.0000000000'),
952n/a ('f', '0E1', '0'), # loses exponent information
953n/a ('f', '3.2E1', '32'),
954n/a ('f', '3.2E2', '320'),
955n/a ('f', '3.20E2', '320'),
956n/a ('f', '3.200E2', '320.0'),
957n/a ('f', '3.2E-6', '0.0000032'),
958n/a ('.6f', '0E-15', '0.000000'), # all zeros treated equally
959n/a ('.6f', '0E1', '0.000000'),
960n/a ('.6f', '0', '0.000000'),
961n/a ('.0f', '0', '0'), # no decimal point
962n/a ('.0f', '0e-2', '0'),
963n/a ('.0f', '3.14159265', '3'),
964n/a ('.1f', '3.14159265', '3.1'),
965n/a ('.4f', '3.14159265', '3.1416'),
966n/a ('.6f', '3.14159265', '3.141593'),
967n/a ('.7f', '3.14159265', '3.1415926'), # round-half-even!
968n/a ('.8f', '3.14159265', '3.14159265'),
969n/a ('.9f', '3.14159265', '3.141592650'),
970n/a
971n/a ('g', '0', '0'),
972n/a ('g', '0.0', '0.0'),
973n/a ('g', '0E1', '0e+1'),
974n/a ('G', '0E1', '0E+1'),
975n/a ('g', '0E-5', '0.00000'),
976n/a ('g', '0E-6', '0.000000'),
977n/a ('g', '0E-7', '0e-7'),
978n/a ('g', '-0E2', '-0e+2'),
979n/a ('.0g', '3.14159265', '3'), # 0 sig fig -> 1 sig fig
980n/a ('.0n', '3.14159265', '3'), # same for 'n'
981n/a ('.1g', '3.14159265', '3'),
982n/a ('.2g', '3.14159265', '3.1'),
983n/a ('.5g', '3.14159265', '3.1416'),
984n/a ('.7g', '3.14159265', '3.141593'),
985n/a ('.8g', '3.14159265', '3.1415926'), # round-half-even!
986n/a ('.9g', '3.14159265', '3.14159265'),
987n/a ('.10g', '3.14159265', '3.14159265'), # don't pad
988n/a
989n/a ('%', '0E1', '0%'),
990n/a ('%', '0E0', '0%'),
991n/a ('%', '0E-1', '0%'),
992n/a ('%', '0E-2', '0%'),
993n/a ('%', '0E-3', '0.0%'),
994n/a ('%', '0E-4', '0.00%'),
995n/a
996n/a ('.3%', '0', '0.000%'), # all zeros treated equally
997n/a ('.3%', '0E10', '0.000%'),
998n/a ('.3%', '0E-10', '0.000%'),
999n/a ('.3%', '2.34', '234.000%'),
1000n/a ('.3%', '1.234567', '123.457%'),
1001n/a ('.0%', '1.23', '123%'),
1002n/a
1003n/a ('e', 'NaN', 'NaN'),
1004n/a ('f', '-NaN123', '-NaN123'),
1005n/a ('+g', 'NaN456', '+NaN456'),
1006n/a ('.3e', 'Inf', 'Infinity'),
1007n/a ('.16f', '-Inf', '-Infinity'),
1008n/a ('.0g', '-sNaN', '-sNaN'),
1009n/a
1010n/a ('', '1.00', '1.00'),
1011n/a
1012n/a # test alignment and padding
1013n/a ('6', '123', ' 123'),
1014n/a ('<6', '123', '123 '),
1015n/a ('>6', '123', ' 123'),
1016n/a ('^6', '123', ' 123 '),
1017n/a ('=+6', '123', '+ 123'),
1018n/a ('#<10', 'NaN', 'NaN#######'),
1019n/a ('#<10', '-4.3', '-4.3######'),
1020n/a ('#<+10', '0.0130', '+0.0130###'),
1021n/a ('#< 10', '0.0130', ' 0.0130###'),
1022n/a ('@>10', '-Inf', '@-Infinity'),
1023n/a ('#>5', '-Inf', '-Infinity'),
1024n/a ('?^5', '123', '?123?'),
1025n/a ('%^6', '123', '%123%%'),
1026n/a (' ^6', '-45.6', '-45.6 '),
1027n/a ('/=10', '-45.6', '-/////45.6'),
1028n/a ('/=+10', '45.6', '+/////45.6'),
1029n/a ('/= 10', '45.6', ' /////45.6'),
1030n/a ('\x00=10', '-inf', '-\x00Infinity'),
1031n/a ('\x00^16', '-inf', '\x00\x00\x00-Infinity\x00\x00\x00\x00'),
1032n/a ('\x00>10', '1.2345', '\x00\x00\x00\x001.2345'),
1033n/a ('\x00<10', '1.2345', '1.2345\x00\x00\x00\x00'),
1034n/a
1035n/a # thousands separator
1036n/a (',', '1234567', '1,234,567'),
1037n/a (',', '123456', '123,456'),
1038n/a (',', '12345', '12,345'),
1039n/a (',', '1234', '1,234'),
1040n/a (',', '123', '123'),
1041n/a (',', '12', '12'),
1042n/a (',', '1', '1'),
1043n/a (',', '0', '0'),
1044n/a (',', '-1234567', '-1,234,567'),
1045n/a (',', '-123456', '-123,456'),
1046n/a ('7,', '123456', '123,456'),
1047n/a ('8,', '123456', ' 123,456'),
1048n/a ('08,', '123456', '0,123,456'), # special case: extra 0 needed
1049n/a ('+08,', '123456', '+123,456'), # but not if there's a sign
1050n/a (' 08,', '123456', ' 123,456'),
1051n/a ('08,', '-123456', '-123,456'),
1052n/a ('+09,', '123456', '+0,123,456'),
1053n/a # ... with fractional part...
1054n/a ('07,', '1234.56', '1,234.56'),
1055n/a ('08,', '1234.56', '1,234.56'),
1056n/a ('09,', '1234.56', '01,234.56'),
1057n/a ('010,', '1234.56', '001,234.56'),
1058n/a ('011,', '1234.56', '0,001,234.56'),
1059n/a ('012,', '1234.56', '0,001,234.56'),
1060n/a ('08,.1f', '1234.5', '01,234.5'),
1061n/a # no thousands separators in fraction part
1062n/a (',', '1.23456789', '1.23456789'),
1063n/a (',%', '123.456789', '12,345.6789%'),
1064n/a (',e', '123456', '1.23456e+5'),
1065n/a (',E', '123456', '1.23456E+5'),
1066n/a
1067n/a # issue 6850
1068n/a ('a=-7.0', '0.12345', 'aaaa0.1'),
1069n/a
1070n/a # issue 22090
1071n/a ('<^+15.20%', 'inf', '<<+Infinity%<<<'),
1072n/a ('\x07>,%', 'sNaN1234567', 'sNaN1234567%'),
1073n/a ('=10.10%', 'NaN123', ' NaN123%'),
1074n/a ]
1075n/a for fmt, d, result in test_values:
1076n/a self.assertEqual(format(Decimal(d), fmt), result)
1077n/a
1078n/a # bytes format argument
1079n/a self.assertRaises(TypeError, Decimal(1).__format__, b'-020')
1080n/a
1081n/a def test_n_format(self):
1082n/a Decimal = self.decimal.Decimal
1083n/a
1084n/a try:
1085n/a from locale import CHAR_MAX
1086n/a except ImportError:
1087n/a self.skipTest('locale.CHAR_MAX not available')
1088n/a
1089n/a def make_grouping(lst):
1090n/a return ''.join([chr(x) for x in lst]) if self.decimal == C else lst
1091n/a
1092n/a def get_fmt(x, override=None, fmt='n'):
1093n/a if self.decimal == C:
1094n/a return Decimal(x).__format__(fmt, override)
1095n/a else:
1096n/a return Decimal(x).__format__(fmt, _localeconv=override)
1097n/a
1098n/a # Set up some localeconv-like dictionaries
1099n/a en_US = {
1100n/a 'decimal_point' : '.',
1101n/a 'grouping' : make_grouping([3, 3, 0]),
1102n/a 'thousands_sep' : ','
1103n/a }
1104n/a
1105n/a fr_FR = {
1106n/a 'decimal_point' : ',',
1107n/a 'grouping' : make_grouping([CHAR_MAX]),
1108n/a 'thousands_sep' : ''
1109n/a }
1110n/a
1111n/a ru_RU = {
1112n/a 'decimal_point' : ',',
1113n/a 'grouping': make_grouping([3, 3, 0]),
1114n/a 'thousands_sep' : ' '
1115n/a }
1116n/a
1117n/a crazy = {
1118n/a 'decimal_point' : '&',
1119n/a 'grouping': make_grouping([1, 4, 2, CHAR_MAX]),
1120n/a 'thousands_sep' : '-'
1121n/a }
1122n/a
1123n/a dotsep_wide = {
1124n/a 'decimal_point' : b'\xc2\xbf'.decode('utf-8'),
1125n/a 'grouping': make_grouping([3, 3, 0]),
1126n/a 'thousands_sep' : b'\xc2\xb4'.decode('utf-8')
1127n/a }
1128n/a
1129n/a self.assertEqual(get_fmt(Decimal('12.7'), en_US), '12.7')
1130n/a self.assertEqual(get_fmt(Decimal('12.7'), fr_FR), '12,7')
1131n/a self.assertEqual(get_fmt(Decimal('12.7'), ru_RU), '12,7')
1132n/a self.assertEqual(get_fmt(Decimal('12.7'), crazy), '1-2&7')
1133n/a
1134n/a self.assertEqual(get_fmt(123456789, en_US), '123,456,789')
1135n/a self.assertEqual(get_fmt(123456789, fr_FR), '123456789')
1136n/a self.assertEqual(get_fmt(123456789, ru_RU), '123 456 789')
1137n/a self.assertEqual(get_fmt(1234567890123, crazy), '123456-78-9012-3')
1138n/a
1139n/a self.assertEqual(get_fmt(123456789, en_US, '.6n'), '1.23457e+8')
1140n/a self.assertEqual(get_fmt(123456789, fr_FR, '.6n'), '1,23457e+8')
1141n/a self.assertEqual(get_fmt(123456789, ru_RU, '.6n'), '1,23457e+8')
1142n/a self.assertEqual(get_fmt(123456789, crazy, '.6n'), '1&23457e+8')
1143n/a
1144n/a # zero padding
1145n/a self.assertEqual(get_fmt(1234, fr_FR, '03n'), '1234')
1146n/a self.assertEqual(get_fmt(1234, fr_FR, '04n'), '1234')
1147n/a self.assertEqual(get_fmt(1234, fr_FR, '05n'), '01234')
1148n/a self.assertEqual(get_fmt(1234, fr_FR, '06n'), '001234')
1149n/a
1150n/a self.assertEqual(get_fmt(12345, en_US, '05n'), '12,345')
1151n/a self.assertEqual(get_fmt(12345, en_US, '06n'), '12,345')
1152n/a self.assertEqual(get_fmt(12345, en_US, '07n'), '012,345')
1153n/a self.assertEqual(get_fmt(12345, en_US, '08n'), '0,012,345')
1154n/a self.assertEqual(get_fmt(12345, en_US, '09n'), '0,012,345')
1155n/a self.assertEqual(get_fmt(12345, en_US, '010n'), '00,012,345')
1156n/a
1157n/a self.assertEqual(get_fmt(123456, crazy, '06n'), '1-2345-6')
1158n/a self.assertEqual(get_fmt(123456, crazy, '07n'), '1-2345-6')
1159n/a self.assertEqual(get_fmt(123456, crazy, '08n'), '1-2345-6')
1160n/a self.assertEqual(get_fmt(123456, crazy, '09n'), '01-2345-6')
1161n/a self.assertEqual(get_fmt(123456, crazy, '010n'), '0-01-2345-6')
1162n/a self.assertEqual(get_fmt(123456, crazy, '011n'), '0-01-2345-6')
1163n/a self.assertEqual(get_fmt(123456, crazy, '012n'), '00-01-2345-6')
1164n/a self.assertEqual(get_fmt(123456, crazy, '013n'), '000-01-2345-6')
1165n/a
1166n/a # wide char separator and decimal point
1167n/a self.assertEqual(get_fmt(Decimal('-1.5'), dotsep_wide, '020n'),
1168n/a '-0\u00b4000\u00b4000\u00b4000\u00b4001\u00bf5')
1169n/a
1170n/a @run_with_locale('LC_ALL', 'ps_AF')
1171n/a def test_wide_char_separator_decimal_point(self):
1172n/a # locale with wide char separator and decimal point
1173n/a import locale
1174n/a Decimal = self.decimal.Decimal
1175n/a
1176n/a decimal_point = locale.localeconv()['decimal_point']
1177n/a thousands_sep = locale.localeconv()['thousands_sep']
1178n/a if decimal_point != '\u066b':
1179n/a self.skipTest('inappropriate decimal point separator'
1180n/a '({!a} not {!a})'.format(decimal_point, '\u066b'))
1181n/a if thousands_sep != '\u066c':
1182n/a self.skipTest('inappropriate thousands separator'
1183n/a '({!a} not {!a})'.format(thousands_sep, '\u066c'))
1184n/a
1185n/a self.assertEqual(format(Decimal('100000000.123'), 'n'),
1186n/a '100\u066c000\u066c000\u066b123')
1187n/a
1188n/aclass CFormatTest(FormatTest):
1189n/a decimal = C
1190n/aclass PyFormatTest(FormatTest):
1191n/a decimal = P
1192n/a
1193n/aclass ArithmeticOperatorsTest(unittest.TestCase):
1194n/a '''Unit tests for all arithmetic operators, binary and unary.'''
1195n/a
1196n/a def test_addition(self):
1197n/a Decimal = self.decimal.Decimal
1198n/a
1199n/a d1 = Decimal('-11.1')
1200n/a d2 = Decimal('22.2')
1201n/a
1202n/a #two Decimals
1203n/a self.assertEqual(d1+d2, Decimal('11.1'))
1204n/a self.assertEqual(d2+d1, Decimal('11.1'))
1205n/a
1206n/a #with other type, left
1207n/a c = d1 + 5
1208n/a self.assertEqual(c, Decimal('-6.1'))
1209n/a self.assertEqual(type(c), type(d1))
1210n/a
1211n/a #with other type, right
1212n/a c = 5 + d1
1213n/a self.assertEqual(c, Decimal('-6.1'))
1214n/a self.assertEqual(type(c), type(d1))
1215n/a
1216n/a #inline with decimal
1217n/a d1 += d2
1218n/a self.assertEqual(d1, Decimal('11.1'))
1219n/a
1220n/a #inline with other type
1221n/a d1 += 5
1222n/a self.assertEqual(d1, Decimal('16.1'))
1223n/a
1224n/a def test_subtraction(self):
1225n/a Decimal = self.decimal.Decimal
1226n/a
1227n/a d1 = Decimal('-11.1')
1228n/a d2 = Decimal('22.2')
1229n/a
1230n/a #two Decimals
1231n/a self.assertEqual(d1-d2, Decimal('-33.3'))
1232n/a self.assertEqual(d2-d1, Decimal('33.3'))
1233n/a
1234n/a #with other type, left
1235n/a c = d1 - 5
1236n/a self.assertEqual(c, Decimal('-16.1'))
1237n/a self.assertEqual(type(c), type(d1))
1238n/a
1239n/a #with other type, right
1240n/a c = 5 - d1
1241n/a self.assertEqual(c, Decimal('16.1'))
1242n/a self.assertEqual(type(c), type(d1))
1243n/a
1244n/a #inline with decimal
1245n/a d1 -= d2
1246n/a self.assertEqual(d1, Decimal('-33.3'))
1247n/a
1248n/a #inline with other type
1249n/a d1 -= 5
1250n/a self.assertEqual(d1, Decimal('-38.3'))
1251n/a
1252n/a def test_multiplication(self):
1253n/a Decimal = self.decimal.Decimal
1254n/a
1255n/a d1 = Decimal('-5')
1256n/a d2 = Decimal('3')
1257n/a
1258n/a #two Decimals
1259n/a self.assertEqual(d1*d2, Decimal('-15'))
1260n/a self.assertEqual(d2*d1, Decimal('-15'))
1261n/a
1262n/a #with other type, left
1263n/a c = d1 * 5
1264n/a self.assertEqual(c, Decimal('-25'))
1265n/a self.assertEqual(type(c), type(d1))
1266n/a
1267n/a #with other type, right
1268n/a c = 5 * d1
1269n/a self.assertEqual(c, Decimal('-25'))
1270n/a self.assertEqual(type(c), type(d1))
1271n/a
1272n/a #inline with decimal
1273n/a d1 *= d2
1274n/a self.assertEqual(d1, Decimal('-15'))
1275n/a
1276n/a #inline with other type
1277n/a d1 *= 5
1278n/a self.assertEqual(d1, Decimal('-75'))
1279n/a
1280n/a def test_division(self):
1281n/a Decimal = self.decimal.Decimal
1282n/a
1283n/a d1 = Decimal('-5')
1284n/a d2 = Decimal('2')
1285n/a
1286n/a #two Decimals
1287n/a self.assertEqual(d1/d2, Decimal('-2.5'))
1288n/a self.assertEqual(d2/d1, Decimal('-0.4'))
1289n/a
1290n/a #with other type, left
1291n/a c = d1 / 4
1292n/a self.assertEqual(c, Decimal('-1.25'))
1293n/a self.assertEqual(type(c), type(d1))
1294n/a
1295n/a #with other type, right
1296n/a c = 4 / d1
1297n/a self.assertEqual(c, Decimal('-0.8'))
1298n/a self.assertEqual(type(c), type(d1))
1299n/a
1300n/a #inline with decimal
1301n/a d1 /= d2
1302n/a self.assertEqual(d1, Decimal('-2.5'))
1303n/a
1304n/a #inline with other type
1305n/a d1 /= 4
1306n/a self.assertEqual(d1, Decimal('-0.625'))
1307n/a
1308n/a def test_floor_division(self):
1309n/a Decimal = self.decimal.Decimal
1310n/a
1311n/a d1 = Decimal('5')
1312n/a d2 = Decimal('2')
1313n/a
1314n/a #two Decimals
1315n/a self.assertEqual(d1//d2, Decimal('2'))
1316n/a self.assertEqual(d2//d1, Decimal('0'))
1317n/a
1318n/a #with other type, left
1319n/a c = d1 // 4
1320n/a self.assertEqual(c, Decimal('1'))
1321n/a self.assertEqual(type(c), type(d1))
1322n/a
1323n/a #with other type, right
1324n/a c = 7 // d1
1325n/a self.assertEqual(c, Decimal('1'))
1326n/a self.assertEqual(type(c), type(d1))
1327n/a
1328n/a #inline with decimal
1329n/a d1 //= d2
1330n/a self.assertEqual(d1, Decimal('2'))
1331n/a
1332n/a #inline with other type
1333n/a d1 //= 2
1334n/a self.assertEqual(d1, Decimal('1'))
1335n/a
1336n/a def test_powering(self):
1337n/a Decimal = self.decimal.Decimal
1338n/a
1339n/a d1 = Decimal('5')
1340n/a d2 = Decimal('2')
1341n/a
1342n/a #two Decimals
1343n/a self.assertEqual(d1**d2, Decimal('25'))
1344n/a self.assertEqual(d2**d1, Decimal('32'))
1345n/a
1346n/a #with other type, left
1347n/a c = d1 ** 4
1348n/a self.assertEqual(c, Decimal('625'))
1349n/a self.assertEqual(type(c), type(d1))
1350n/a
1351n/a #with other type, right
1352n/a c = 7 ** d1
1353n/a self.assertEqual(c, Decimal('16807'))
1354n/a self.assertEqual(type(c), type(d1))
1355n/a
1356n/a #inline with decimal
1357n/a d1 **= d2
1358n/a self.assertEqual(d1, Decimal('25'))
1359n/a
1360n/a #inline with other type
1361n/a d1 **= 4
1362n/a self.assertEqual(d1, Decimal('390625'))
1363n/a
1364n/a def test_module(self):
1365n/a Decimal = self.decimal.Decimal
1366n/a
1367n/a d1 = Decimal('5')
1368n/a d2 = Decimal('2')
1369n/a
1370n/a #two Decimals
1371n/a self.assertEqual(d1%d2, Decimal('1'))
1372n/a self.assertEqual(d2%d1, Decimal('2'))
1373n/a
1374n/a #with other type, left
1375n/a c = d1 % 4
1376n/a self.assertEqual(c, Decimal('1'))
1377n/a self.assertEqual(type(c), type(d1))
1378n/a
1379n/a #with other type, right
1380n/a c = 7 % d1
1381n/a self.assertEqual(c, Decimal('2'))
1382n/a self.assertEqual(type(c), type(d1))
1383n/a
1384n/a #inline with decimal
1385n/a d1 %= d2
1386n/a self.assertEqual(d1, Decimal('1'))
1387n/a
1388n/a #inline with other type
1389n/a d1 %= 4
1390n/a self.assertEqual(d1, Decimal('1'))
1391n/a
1392n/a def test_floor_div_module(self):
1393n/a Decimal = self.decimal.Decimal
1394n/a
1395n/a d1 = Decimal('5')
1396n/a d2 = Decimal('2')
1397n/a
1398n/a #two Decimals
1399n/a (p, q) = divmod(d1, d2)
1400n/a self.assertEqual(p, Decimal('2'))
1401n/a self.assertEqual(q, Decimal('1'))
1402n/a self.assertEqual(type(p), type(d1))
1403n/a self.assertEqual(type(q), type(d1))
1404n/a
1405n/a #with other type, left
1406n/a (p, q) = divmod(d1, 4)
1407n/a self.assertEqual(p, Decimal('1'))
1408n/a self.assertEqual(q, Decimal('1'))
1409n/a self.assertEqual(type(p), type(d1))
1410n/a self.assertEqual(type(q), type(d1))
1411n/a
1412n/a #with other type, right
1413n/a (p, q) = divmod(7, d1)
1414n/a self.assertEqual(p, Decimal('1'))
1415n/a self.assertEqual(q, Decimal('2'))
1416n/a self.assertEqual(type(p), type(d1))
1417n/a self.assertEqual(type(q), type(d1))
1418n/a
1419n/a def test_unary_operators(self):
1420n/a Decimal = self.decimal.Decimal
1421n/a
1422n/a self.assertEqual(+Decimal(45), Decimal(+45)) # +
1423n/a self.assertEqual(-Decimal(45), Decimal(-45)) # -
1424n/a self.assertEqual(abs(Decimal(45)), abs(Decimal(-45))) # abs
1425n/a
1426n/a def test_nan_comparisons(self):
1427n/a # comparisons involving signaling nans signal InvalidOperation
1428n/a
1429n/a # order comparisons (<, <=, >, >=) involving only quiet nans
1430n/a # also signal InvalidOperation
1431n/a
1432n/a # equality comparisons (==, !=) involving only quiet nans
1433n/a # don't signal, but return False or True respectively.
1434n/a Decimal = self.decimal.Decimal
1435n/a InvalidOperation = self.decimal.InvalidOperation
1436n/a localcontext = self.decimal.localcontext
1437n/a
1438n/a n = Decimal('NaN')
1439n/a s = Decimal('sNaN')
1440n/a i = Decimal('Inf')
1441n/a f = Decimal('2')
1442n/a
1443n/a qnan_pairs = (n, n), (n, i), (i, n), (n, f), (f, n)
1444n/a snan_pairs = (s, n), (n, s), (s, i), (i, s), (s, f), (f, s), (s, s)
1445n/a order_ops = operator.lt, operator.le, operator.gt, operator.ge
1446n/a equality_ops = operator.eq, operator.ne
1447n/a
1448n/a # results when InvalidOperation is not trapped
1449n/a for x, y in qnan_pairs + snan_pairs:
1450n/a for op in order_ops + equality_ops:
1451n/a got = op(x, y)
1452n/a expected = True if op is operator.ne else False
1453n/a self.assertIs(expected, got,
1454n/a "expected {0!r} for operator.{1}({2!r}, {3!r}); "
1455n/a "got {4!r}".format(
1456n/a expected, op.__name__, x, y, got))
1457n/a
1458n/a # repeat the above, but this time trap the InvalidOperation
1459n/a with localcontext() as ctx:
1460n/a ctx.traps[InvalidOperation] = 1
1461n/a
1462n/a for x, y in qnan_pairs:
1463n/a for op in equality_ops:
1464n/a got = op(x, y)
1465n/a expected = True if op is operator.ne else False
1466n/a self.assertIs(expected, got,
1467n/a "expected {0!r} for "
1468n/a "operator.{1}({2!r}, {3!r}); "
1469n/a "got {4!r}".format(
1470n/a expected, op.__name__, x, y, got))
1471n/a
1472n/a for x, y in snan_pairs:
1473n/a for op in equality_ops:
1474n/a self.assertRaises(InvalidOperation, operator.eq, x, y)
1475n/a self.assertRaises(InvalidOperation, operator.ne, x, y)
1476n/a
1477n/a for x, y in qnan_pairs + snan_pairs:
1478n/a for op in order_ops:
1479n/a self.assertRaises(InvalidOperation, op, x, y)
1480n/a
1481n/a def test_copy_sign(self):
1482n/a Decimal = self.decimal.Decimal
1483n/a
1484n/a d = Decimal(1).copy_sign(Decimal(-2))
1485n/a self.assertEqual(Decimal(1).copy_sign(-2), d)
1486n/a self.assertRaises(TypeError, Decimal(1).copy_sign, '-2')
1487n/a
1488n/aclass CArithmeticOperatorsTest(ArithmeticOperatorsTest):
1489n/a decimal = C
1490n/aclass PyArithmeticOperatorsTest(ArithmeticOperatorsTest):
1491n/a decimal = P
1492n/a
1493n/a# The following are two functions used to test threading in the next class
1494n/a
1495n/adef thfunc1(cls):
1496n/a Decimal = cls.decimal.Decimal
1497n/a InvalidOperation = cls.decimal.InvalidOperation
1498n/a DivisionByZero = cls.decimal.DivisionByZero
1499n/a Overflow = cls.decimal.Overflow
1500n/a Underflow = cls.decimal.Underflow
1501n/a Inexact = cls.decimal.Inexact
1502n/a getcontext = cls.decimal.getcontext
1503n/a localcontext = cls.decimal.localcontext
1504n/a
1505n/a d1 = Decimal(1)
1506n/a d3 = Decimal(3)
1507n/a test1 = d1/d3
1508n/a
1509n/a cls.finish1.set()
1510n/a cls.synchro.wait()
1511n/a
1512n/a test2 = d1/d3
1513n/a with localcontext() as c2:
1514n/a cls.assertTrue(c2.flags[Inexact])
1515n/a cls.assertRaises(DivisionByZero, c2.divide, d1, 0)
1516n/a cls.assertTrue(c2.flags[DivisionByZero])
1517n/a with localcontext() as c3:
1518n/a cls.assertTrue(c3.flags[Inexact])
1519n/a cls.assertTrue(c3.flags[DivisionByZero])
1520n/a cls.assertRaises(InvalidOperation, c3.compare, d1, Decimal('sNaN'))
1521n/a cls.assertTrue(c3.flags[InvalidOperation])
1522n/a del c3
1523n/a cls.assertFalse(c2.flags[InvalidOperation])
1524n/a del c2
1525n/a
1526n/a cls.assertEqual(test1, Decimal('0.333333333333333333333333'))
1527n/a cls.assertEqual(test2, Decimal('0.333333333333333333333333'))
1528n/a
1529n/a c1 = getcontext()
1530n/a cls.assertTrue(c1.flags[Inexact])
1531n/a for sig in Overflow, Underflow, DivisionByZero, InvalidOperation:
1532n/a cls.assertFalse(c1.flags[sig])
1533n/a
1534n/adef thfunc2(cls):
1535n/a Decimal = cls.decimal.Decimal
1536n/a InvalidOperation = cls.decimal.InvalidOperation
1537n/a DivisionByZero = cls.decimal.DivisionByZero
1538n/a Overflow = cls.decimal.Overflow
1539n/a Underflow = cls.decimal.Underflow
1540n/a Inexact = cls.decimal.Inexact
1541n/a getcontext = cls.decimal.getcontext
1542n/a localcontext = cls.decimal.localcontext
1543n/a
1544n/a d1 = Decimal(1)
1545n/a d3 = Decimal(3)
1546n/a test1 = d1/d3
1547n/a
1548n/a thiscontext = getcontext()
1549n/a thiscontext.prec = 18
1550n/a test2 = d1/d3
1551n/a
1552n/a with localcontext() as c2:
1553n/a cls.assertTrue(c2.flags[Inexact])
1554n/a cls.assertRaises(Overflow, c2.multiply, Decimal('1e425000000'), 999)
1555n/a cls.assertTrue(c2.flags[Overflow])
1556n/a with localcontext(thiscontext) as c3:
1557n/a cls.assertTrue(c3.flags[Inexact])
1558n/a cls.assertFalse(c3.flags[Overflow])
1559n/a c3.traps[Underflow] = True
1560n/a cls.assertRaises(Underflow, c3.divide, Decimal('1e-425000000'), 999)
1561n/a cls.assertTrue(c3.flags[Underflow])
1562n/a del c3
1563n/a cls.assertFalse(c2.flags[Underflow])
1564n/a cls.assertFalse(c2.traps[Underflow])
1565n/a del c2
1566n/a
1567n/a cls.synchro.set()
1568n/a cls.finish2.set()
1569n/a
1570n/a cls.assertEqual(test1, Decimal('0.333333333333333333333333'))
1571n/a cls.assertEqual(test2, Decimal('0.333333333333333333'))
1572n/a
1573n/a cls.assertFalse(thiscontext.traps[Underflow])
1574n/a cls.assertTrue(thiscontext.flags[Inexact])
1575n/a for sig in Overflow, Underflow, DivisionByZero, InvalidOperation:
1576n/a cls.assertFalse(thiscontext.flags[sig])
1577n/a
1578n/aclass ThreadingTest(unittest.TestCase):
1579n/a '''Unit tests for thread local contexts in Decimal.'''
1580n/a
1581n/a # Take care executing this test from IDLE, there's an issue in threading
1582n/a # that hangs IDLE and I couldn't find it
1583n/a
1584n/a def test_threading(self):
1585n/a DefaultContext = self.decimal.DefaultContext
1586n/a
1587n/a if self.decimal == C and not self.decimal.HAVE_THREADS:
1588n/a self.skipTest("compiled without threading")
1589n/a # Test the "threading isolation" of a Context. Also test changing
1590n/a # the DefaultContext, which acts as a template for the thread-local
1591n/a # contexts.
1592n/a save_prec = DefaultContext.prec
1593n/a save_emax = DefaultContext.Emax
1594n/a save_emin = DefaultContext.Emin
1595n/a DefaultContext.prec = 24
1596n/a DefaultContext.Emax = 425000000
1597n/a DefaultContext.Emin = -425000000
1598n/a
1599n/a self.synchro = threading.Event()
1600n/a self.finish1 = threading.Event()
1601n/a self.finish2 = threading.Event()
1602n/a
1603n/a th1 = threading.Thread(target=thfunc1, args=(self,))
1604n/a th2 = threading.Thread(target=thfunc2, args=(self,))
1605n/a
1606n/a th1.start()
1607n/a th2.start()
1608n/a
1609n/a self.finish1.wait()
1610n/a self.finish2.wait()
1611n/a
1612n/a for sig in Signals[self.decimal]:
1613n/a self.assertFalse(DefaultContext.flags[sig])
1614n/a
1615n/a DefaultContext.prec = save_prec
1616n/a DefaultContext.Emax = save_emax
1617n/a DefaultContext.Emin = save_emin
1618n/a
1619n/a@unittest.skipUnless(threading, 'threading required')
1620n/aclass CThreadingTest(ThreadingTest):
1621n/a decimal = C
1622n/a@unittest.skipUnless(threading, 'threading required')
1623n/aclass PyThreadingTest(ThreadingTest):
1624n/a decimal = P
1625n/a
1626n/aclass UsabilityTest(unittest.TestCase):
1627n/a '''Unit tests for Usability cases of Decimal.'''
1628n/a
1629n/a def test_comparison_operators(self):
1630n/a
1631n/a Decimal = self.decimal.Decimal
1632n/a
1633n/a da = Decimal('23.42')
1634n/a db = Decimal('23.42')
1635n/a dc = Decimal('45')
1636n/a
1637n/a #two Decimals
1638n/a self.assertGreater(dc, da)
1639n/a self.assertGreaterEqual(dc, da)
1640n/a self.assertLess(da, dc)
1641n/a self.assertLessEqual(da, dc)
1642n/a self.assertEqual(da, db)
1643n/a self.assertNotEqual(da, dc)
1644n/a self.assertLessEqual(da, db)
1645n/a self.assertGreaterEqual(da, db)
1646n/a
1647n/a #a Decimal and an int
1648n/a self.assertGreater(dc, 23)
1649n/a self.assertLess(23, dc)
1650n/a self.assertEqual(dc, 45)
1651n/a
1652n/a #a Decimal and uncomparable
1653n/a self.assertNotEqual(da, 'ugly')
1654n/a self.assertNotEqual(da, 32.7)
1655n/a self.assertNotEqual(da, object())
1656n/a self.assertNotEqual(da, object)
1657n/a
1658n/a # sortable
1659n/a a = list(map(Decimal, range(100)))
1660n/a b = a[:]
1661n/a random.shuffle(a)
1662n/a a.sort()
1663n/a self.assertEqual(a, b)
1664n/a
1665n/a def test_decimal_float_comparison(self):
1666n/a Decimal = self.decimal.Decimal
1667n/a
1668n/a da = Decimal('0.25')
1669n/a db = Decimal('3.0')
1670n/a self.assertLess(da, 3.0)
1671n/a self.assertLessEqual(da, 3.0)
1672n/a self.assertGreater(db, 0.25)
1673n/a self.assertGreaterEqual(db, 0.25)
1674n/a self.assertNotEqual(da, 1.5)
1675n/a self.assertEqual(da, 0.25)
1676n/a self.assertGreater(3.0, da)
1677n/a self.assertGreaterEqual(3.0, da)
1678n/a self.assertLess(0.25, db)
1679n/a self.assertLessEqual(0.25, db)
1680n/a self.assertNotEqual(0.25, db)
1681n/a self.assertEqual(3.0, db)
1682n/a self.assertNotEqual(0.1, Decimal('0.1'))
1683n/a
1684n/a def test_decimal_complex_comparison(self):
1685n/a Decimal = self.decimal.Decimal
1686n/a
1687n/a da = Decimal('0.25')
1688n/a db = Decimal('3.0')
1689n/a self.assertNotEqual(da, (1.5+0j))
1690n/a self.assertNotEqual((1.5+0j), da)
1691n/a self.assertEqual(da, (0.25+0j))
1692n/a self.assertEqual((0.25+0j), da)
1693n/a self.assertEqual((3.0+0j), db)
1694n/a self.assertEqual(db, (3.0+0j))
1695n/a
1696n/a self.assertNotEqual(db, (3.0+1j))
1697n/a self.assertNotEqual((3.0+1j), db)
1698n/a
1699n/a self.assertIs(db.__lt__(3.0+0j), NotImplemented)
1700n/a self.assertIs(db.__le__(3.0+0j), NotImplemented)
1701n/a self.assertIs(db.__gt__(3.0+0j), NotImplemented)
1702n/a self.assertIs(db.__le__(3.0+0j), NotImplemented)
1703n/a
1704n/a def test_decimal_fraction_comparison(self):
1705n/a D = self.decimal.Decimal
1706n/a F = fractions[self.decimal].Fraction
1707n/a Context = self.decimal.Context
1708n/a localcontext = self.decimal.localcontext
1709n/a InvalidOperation = self.decimal.InvalidOperation
1710n/a
1711n/a
1712n/a emax = C.MAX_EMAX if C else 999999999
1713n/a emin = C.MIN_EMIN if C else -999999999
1714n/a etiny = C.MIN_ETINY if C else -1999999997
1715n/a c = Context(Emax=emax, Emin=emin)
1716n/a
1717n/a with localcontext(c):
1718n/a c.prec = emax
1719n/a self.assertLess(D(0), F(1,9999999999999999999999999999999999999))
1720n/a self.assertLess(F(-1,9999999999999999999999999999999999999), D(0))
1721n/a self.assertLess(F(0,1), D("1e" + str(etiny)))
1722n/a self.assertLess(D("-1e" + str(etiny)), F(0,1))
1723n/a self.assertLess(F(0,9999999999999999999999999), D("1e" + str(etiny)))
1724n/a self.assertLess(D("-1e" + str(etiny)), F(0,9999999999999999999999999))
1725n/a
1726n/a self.assertEqual(D("0.1"), F(1,10))
1727n/a self.assertEqual(F(1,10), D("0.1"))
1728n/a
1729n/a c.prec = 300
1730n/a self.assertNotEqual(D(1)/3, F(1,3))
1731n/a self.assertNotEqual(F(1,3), D(1)/3)
1732n/a
1733n/a self.assertLessEqual(F(120984237, 9999999999), D("9e" + str(emax)))
1734n/a self.assertGreaterEqual(D("9e" + str(emax)), F(120984237, 9999999999))
1735n/a
1736n/a self.assertGreater(D('inf'), F(99999999999,123))
1737n/a self.assertGreater(D('inf'), F(-99999999999,123))
1738n/a self.assertLess(D('-inf'), F(99999999999,123))
1739n/a self.assertLess(D('-inf'), F(-99999999999,123))
1740n/a
1741n/a self.assertRaises(InvalidOperation, D('nan').__gt__, F(-9,123))
1742n/a self.assertIs(NotImplemented, F(-9,123).__lt__(D('nan')))
1743n/a self.assertNotEqual(D('nan'), F(-9,123))
1744n/a self.assertNotEqual(F(-9,123), D('nan'))
1745n/a
1746n/a def test_copy_and_deepcopy_methods(self):
1747n/a Decimal = self.decimal.Decimal
1748n/a
1749n/a d = Decimal('43.24')
1750n/a c = copy.copy(d)
1751n/a self.assertEqual(id(c), id(d))
1752n/a dc = copy.deepcopy(d)
1753n/a self.assertEqual(id(dc), id(d))
1754n/a
1755n/a def test_hash_method(self):
1756n/a
1757n/a Decimal = self.decimal.Decimal
1758n/a localcontext = self.decimal.localcontext
1759n/a
1760n/a def hashit(d):
1761n/a a = hash(d)
1762n/a b = d.__hash__()
1763n/a self.assertEqual(a, b)
1764n/a return a
1765n/a
1766n/a #just that it's hashable
1767n/a hashit(Decimal(23))
1768n/a hashit(Decimal('Infinity'))
1769n/a hashit(Decimal('-Infinity'))
1770n/a hashit(Decimal('nan123'))
1771n/a hashit(Decimal('-NaN'))
1772n/a
1773n/a test_values = [Decimal(sign*(2**m + n))
1774n/a for m in [0, 14, 15, 16, 17, 30, 31,
1775n/a 32, 33, 61, 62, 63, 64, 65, 66]
1776n/a for n in range(-10, 10)
1777n/a for sign in [-1, 1]]
1778n/a test_values.extend([
1779n/a Decimal("-1"), # ==> -2
1780n/a Decimal("-0"), # zeros
1781n/a Decimal("0.00"),
1782n/a Decimal("-0.000"),
1783n/a Decimal("0E10"),
1784n/a Decimal("-0E12"),
1785n/a Decimal("10.0"), # negative exponent
1786n/a Decimal("-23.00000"),
1787n/a Decimal("1230E100"), # positive exponent
1788n/a Decimal("-4.5678E50"),
1789n/a # a value for which hash(n) != hash(n % (2**64-1))
1790n/a # in Python pre-2.6
1791n/a Decimal(2**64 + 2**32 - 1),
1792n/a # selection of values which fail with the old (before
1793n/a # version 2.6) long.__hash__
1794n/a Decimal("1.634E100"),
1795n/a Decimal("90.697E100"),
1796n/a Decimal("188.83E100"),
1797n/a Decimal("1652.9E100"),
1798n/a Decimal("56531E100"),
1799n/a ])
1800n/a
1801n/a # check that hash(d) == hash(int(d)) for integral values
1802n/a for value in test_values:
1803n/a self.assertEqual(hashit(value), hashit(int(value)))
1804n/a
1805n/a #the same hash that to an int
1806n/a self.assertEqual(hashit(Decimal(23)), hashit(23))
1807n/a self.assertRaises(TypeError, hash, Decimal('sNaN'))
1808n/a self.assertTrue(hashit(Decimal('Inf')))
1809n/a self.assertTrue(hashit(Decimal('-Inf')))
1810n/a
1811n/a # check that the hashes of a Decimal float match when they
1812n/a # represent exactly the same values
1813n/a test_strings = ['inf', '-Inf', '0.0', '-.0e1',
1814n/a '34.0', '2.5', '112390.625', '-0.515625']
1815n/a for s in test_strings:
1816n/a f = float(s)
1817n/a d = Decimal(s)
1818n/a self.assertEqual(hashit(f), hashit(d))
1819n/a
1820n/a with localcontext() as c:
1821n/a # check that the value of the hash doesn't depend on the
1822n/a # current context (issue #1757)
1823n/a x = Decimal("123456789.1")
1824n/a
1825n/a c.prec = 6
1826n/a h1 = hashit(x)
1827n/a c.prec = 10
1828n/a h2 = hashit(x)
1829n/a c.prec = 16
1830n/a h3 = hashit(x)
1831n/a
1832n/a self.assertEqual(h1, h2)
1833n/a self.assertEqual(h1, h3)
1834n/a
1835n/a c.prec = 10000
1836n/a x = 1100 ** 1248
1837n/a self.assertEqual(hashit(Decimal(x)), hashit(x))
1838n/a
1839n/a def test_min_and_max_methods(self):
1840n/a Decimal = self.decimal.Decimal
1841n/a
1842n/a d1 = Decimal('15.32')
1843n/a d2 = Decimal('28.5')
1844n/a l1 = 15
1845n/a l2 = 28
1846n/a
1847n/a #between Decimals
1848n/a self.assertIs(min(d1,d2), d1)
1849n/a self.assertIs(min(d2,d1), d1)
1850n/a self.assertIs(max(d1,d2), d2)
1851n/a self.assertIs(max(d2,d1), d2)
1852n/a
1853n/a #between Decimal and int
1854n/a self.assertIs(min(d1,l2), d1)
1855n/a self.assertIs(min(l2,d1), d1)
1856n/a self.assertIs(max(l1,d2), d2)
1857n/a self.assertIs(max(d2,l1), d2)
1858n/a
1859n/a def test_as_nonzero(self):
1860n/a Decimal = self.decimal.Decimal
1861n/a
1862n/a #as false
1863n/a self.assertFalse(Decimal(0))
1864n/a #as true
1865n/a self.assertTrue(Decimal('0.372'))
1866n/a
1867n/a def test_tostring_methods(self):
1868n/a #Test str and repr methods.
1869n/a Decimal = self.decimal.Decimal
1870n/a
1871n/a d = Decimal('15.32')
1872n/a self.assertEqual(str(d), '15.32') # str
1873n/a self.assertEqual(repr(d), "Decimal('15.32')") # repr
1874n/a
1875n/a def test_tonum_methods(self):
1876n/a #Test float and int methods.
1877n/a Decimal = self.decimal.Decimal
1878n/a
1879n/a d1 = Decimal('66')
1880n/a d2 = Decimal('15.32')
1881n/a
1882n/a #int
1883n/a self.assertEqual(int(d1), 66)
1884n/a self.assertEqual(int(d2), 15)
1885n/a
1886n/a #float
1887n/a self.assertEqual(float(d1), 66)
1888n/a self.assertEqual(float(d2), 15.32)
1889n/a
1890n/a #floor
1891n/a test_pairs = [
1892n/a ('123.00', 123),
1893n/a ('3.2', 3),
1894n/a ('3.54', 3),
1895n/a ('3.899', 3),
1896n/a ('-2.3', -3),
1897n/a ('-11.0', -11),
1898n/a ('0.0', 0),
1899n/a ('-0E3', 0),
1900n/a ('89891211712379812736.1', 89891211712379812736),
1901n/a ]
1902n/a for d, i in test_pairs:
1903n/a self.assertEqual(math.floor(Decimal(d)), i)
1904n/a self.assertRaises(ValueError, math.floor, Decimal('-NaN'))
1905n/a self.assertRaises(ValueError, math.floor, Decimal('sNaN'))
1906n/a self.assertRaises(ValueError, math.floor, Decimal('NaN123'))
1907n/a self.assertRaises(OverflowError, math.floor, Decimal('Inf'))
1908n/a self.assertRaises(OverflowError, math.floor, Decimal('-Inf'))
1909n/a
1910n/a #ceiling
1911n/a test_pairs = [
1912n/a ('123.00', 123),
1913n/a ('3.2', 4),
1914n/a ('3.54', 4),
1915n/a ('3.899', 4),
1916n/a ('-2.3', -2),
1917n/a ('-11.0', -11),
1918n/a ('0.0', 0),
1919n/a ('-0E3', 0),
1920n/a ('89891211712379812736.1', 89891211712379812737),
1921n/a ]
1922n/a for d, i in test_pairs:
1923n/a self.assertEqual(math.ceil(Decimal(d)), i)
1924n/a self.assertRaises(ValueError, math.ceil, Decimal('-NaN'))
1925n/a self.assertRaises(ValueError, math.ceil, Decimal('sNaN'))
1926n/a self.assertRaises(ValueError, math.ceil, Decimal('NaN123'))
1927n/a self.assertRaises(OverflowError, math.ceil, Decimal('Inf'))
1928n/a self.assertRaises(OverflowError, math.ceil, Decimal('-Inf'))
1929n/a
1930n/a #round, single argument
1931n/a test_pairs = [
1932n/a ('123.00', 123),
1933n/a ('3.2', 3),
1934n/a ('3.54', 4),
1935n/a ('3.899', 4),
1936n/a ('-2.3', -2),
1937n/a ('-11.0', -11),
1938n/a ('0.0', 0),
1939n/a ('-0E3', 0),
1940n/a ('-3.5', -4),
1941n/a ('-2.5', -2),
1942n/a ('-1.5', -2),
1943n/a ('-0.5', 0),
1944n/a ('0.5', 0),
1945n/a ('1.5', 2),
1946n/a ('2.5', 2),
1947n/a ('3.5', 4),
1948n/a ]
1949n/a for d, i in test_pairs:
1950n/a self.assertEqual(round(Decimal(d)), i)
1951n/a self.assertRaises(ValueError, round, Decimal('-NaN'))
1952n/a self.assertRaises(ValueError, round, Decimal('sNaN'))
1953n/a self.assertRaises(ValueError, round, Decimal('NaN123'))
1954n/a self.assertRaises(OverflowError, round, Decimal('Inf'))
1955n/a self.assertRaises(OverflowError, round, Decimal('-Inf'))
1956n/a
1957n/a #round, two arguments; this is essentially equivalent
1958n/a #to quantize, which is already extensively tested
1959n/a test_triples = [
1960n/a ('123.456', -4, '0E+4'),
1961n/a ('123.456', -3, '0E+3'),
1962n/a ('123.456', -2, '1E+2'),
1963n/a ('123.456', -1, '1.2E+2'),
1964n/a ('123.456', 0, '123'),
1965n/a ('123.456', 1, '123.5'),
1966n/a ('123.456', 2, '123.46'),
1967n/a ('123.456', 3, '123.456'),
1968n/a ('123.456', 4, '123.4560'),
1969n/a ('123.455', 2, '123.46'),
1970n/a ('123.445', 2, '123.44'),
1971n/a ('Inf', 4, 'NaN'),
1972n/a ('-Inf', -23, 'NaN'),
1973n/a ('sNaN314', 3, 'NaN314'),
1974n/a ]
1975n/a for d, n, r in test_triples:
1976n/a self.assertEqual(str(round(Decimal(d), n)), r)
1977n/a
1978n/a def test_nan_to_float(self):
1979n/a # Test conversions of decimal NANs to float.
1980n/a # See http://bugs.python.org/issue15544
1981n/a Decimal = self.decimal.Decimal
1982n/a for s in ('nan', 'nan1234', '-nan', '-nan2468'):
1983n/a f = float(Decimal(s))
1984n/a self.assertTrue(math.isnan(f))
1985n/a sign = math.copysign(1.0, f)
1986n/a self.assertEqual(sign, -1.0 if s.startswith('-') else 1.0)
1987n/a
1988n/a def test_snan_to_float(self):
1989n/a Decimal = self.decimal.Decimal
1990n/a for s in ('snan', '-snan', 'snan1357', '-snan1234'):
1991n/a d = Decimal(s)
1992n/a self.assertRaises(ValueError, float, d)
1993n/a
1994n/a def test_eval_round_trip(self):
1995n/a Decimal = self.decimal.Decimal
1996n/a
1997n/a #with zero
1998n/a d = Decimal( (0, (0,), 0) )
1999n/a self.assertEqual(d, eval(repr(d)))
2000n/a
2001n/a #int
2002n/a d = Decimal( (1, (4, 5), 0) )
2003n/a self.assertEqual(d, eval(repr(d)))
2004n/a
2005n/a #float
2006n/a d = Decimal( (0, (4, 5, 3, 4), -2) )
2007n/a self.assertEqual(d, eval(repr(d)))
2008n/a
2009n/a #weird
2010n/a d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
2011n/a self.assertEqual(d, eval(repr(d)))
2012n/a
2013n/a def test_as_tuple(self):
2014n/a Decimal = self.decimal.Decimal
2015n/a
2016n/a #with zero
2017n/a d = Decimal(0)
2018n/a self.assertEqual(d.as_tuple(), (0, (0,), 0) )
2019n/a
2020n/a #int
2021n/a d = Decimal(-45)
2022n/a self.assertEqual(d.as_tuple(), (1, (4, 5), 0) )
2023n/a
2024n/a #complicated string
2025n/a d = Decimal("-4.34913534E-17")
2026n/a self.assertEqual(d.as_tuple(), (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
2027n/a
2028n/a # The '0' coefficient is implementation specific to decimal.py.
2029n/a # It has no meaning in the C-version and is ignored there.
2030n/a d = Decimal("Infinity")
2031n/a self.assertEqual(d.as_tuple(), (0, (0,), 'F') )
2032n/a
2033n/a #leading zeros in coefficient should be stripped
2034n/a d = Decimal( (0, (0, 0, 4, 0, 5, 3, 4), -2) )
2035n/a self.assertEqual(d.as_tuple(), (0, (4, 0, 5, 3, 4), -2) )
2036n/a d = Decimal( (1, (0, 0, 0), 37) )
2037n/a self.assertEqual(d.as_tuple(), (1, (0,), 37))
2038n/a d = Decimal( (1, (), 37) )
2039n/a self.assertEqual(d.as_tuple(), (1, (0,), 37))
2040n/a
2041n/a #leading zeros in NaN diagnostic info should be stripped
2042n/a d = Decimal( (0, (0, 0, 4, 0, 5, 3, 4), 'n') )
2043n/a self.assertEqual(d.as_tuple(), (0, (4, 0, 5, 3, 4), 'n') )
2044n/a d = Decimal( (1, (0, 0, 0), 'N') )
2045n/a self.assertEqual(d.as_tuple(), (1, (), 'N') )
2046n/a d = Decimal( (1, (), 'n') )
2047n/a self.assertEqual(d.as_tuple(), (1, (), 'n') )
2048n/a
2049n/a # For infinities, decimal.py has always silently accepted any
2050n/a # coefficient tuple.
2051n/a d = Decimal( (0, (0,), 'F') )
2052n/a self.assertEqual(d.as_tuple(), (0, (0,), 'F'))
2053n/a d = Decimal( (0, (4, 5, 3, 4), 'F') )
2054n/a self.assertEqual(d.as_tuple(), (0, (0,), 'F'))
2055n/a d = Decimal( (1, (0, 2, 7, 1), 'F') )
2056n/a self.assertEqual(d.as_tuple(), (1, (0,), 'F'))
2057n/a
2058n/a def test_as_integer_ratio(self):
2059n/a Decimal = self.decimal.Decimal
2060n/a
2061n/a # exceptional cases
2062n/a self.assertRaises(OverflowError,
2063n/a Decimal.as_integer_ratio, Decimal('inf'))
2064n/a self.assertRaises(OverflowError,
2065n/a Decimal.as_integer_ratio, Decimal('-inf'))
2066n/a self.assertRaises(ValueError,
2067n/a Decimal.as_integer_ratio, Decimal('-nan'))
2068n/a self.assertRaises(ValueError,
2069n/a Decimal.as_integer_ratio, Decimal('snan123'))
2070n/a
2071n/a for exp in range(-4, 2):
2072n/a for coeff in range(1000):
2073n/a for sign in '+', '-':
2074n/a d = Decimal('%s%dE%d' % (sign, coeff, exp))
2075n/a pq = d.as_integer_ratio()
2076n/a p, q = pq
2077n/a
2078n/a # check return type
2079n/a self.assertIsInstance(pq, tuple)
2080n/a self.assertIsInstance(p, int)
2081n/a self.assertIsInstance(q, int)
2082n/a
2083n/a # check normalization: q should be positive;
2084n/a # p should be relatively prime to q.
2085n/a self.assertGreater(q, 0)
2086n/a self.assertEqual(math.gcd(p, q), 1)
2087n/a
2088n/a # check that p/q actually gives the correct value
2089n/a self.assertEqual(Decimal(p) / Decimal(q), d)
2090n/a
2091n/a def test_subclassing(self):
2092n/a # Different behaviours when subclassing Decimal
2093n/a Decimal = self.decimal.Decimal
2094n/a
2095n/a class MyDecimal(Decimal):
2096n/a y = None
2097n/a
2098n/a d1 = MyDecimal(1)
2099n/a d2 = MyDecimal(2)
2100n/a d = d1 + d2
2101n/a self.assertIs(type(d), Decimal)
2102n/a
2103n/a d = d1.max(d2)
2104n/a self.assertIs(type(d), Decimal)
2105n/a
2106n/a d = copy.copy(d1)
2107n/a self.assertIs(type(d), MyDecimal)
2108n/a self.assertEqual(d, d1)
2109n/a
2110n/a d = copy.deepcopy(d1)
2111n/a self.assertIs(type(d), MyDecimal)
2112n/a self.assertEqual(d, d1)
2113n/a
2114n/a # Decimal(Decimal)
2115n/a d = Decimal('1.0')
2116n/a x = Decimal(d)
2117n/a self.assertIs(type(x), Decimal)
2118n/a self.assertEqual(x, d)
2119n/a
2120n/a # MyDecimal(Decimal)
2121n/a m = MyDecimal(d)
2122n/a self.assertIs(type(m), MyDecimal)
2123n/a self.assertEqual(m, d)
2124n/a self.assertIs(m.y, None)
2125n/a
2126n/a # Decimal(MyDecimal)
2127n/a x = Decimal(m)
2128n/a self.assertIs(type(x), Decimal)
2129n/a self.assertEqual(x, d)
2130n/a
2131n/a # MyDecimal(MyDecimal)
2132n/a m.y = 9
2133n/a x = MyDecimal(m)
2134n/a self.assertIs(type(x), MyDecimal)
2135n/a self.assertEqual(x, d)
2136n/a self.assertIs(x.y, None)
2137n/a
2138n/a def test_implicit_context(self):
2139n/a Decimal = self.decimal.Decimal
2140n/a getcontext = self.decimal.getcontext
2141n/a
2142n/a # Check results when context given implicitly. (Issue 2478)
2143n/a c = getcontext()
2144n/a self.assertEqual(str(Decimal(0).sqrt()),
2145n/a str(c.sqrt(Decimal(0))))
2146n/a
2147n/a def test_none_args(self):
2148n/a Decimal = self.decimal.Decimal
2149n/a Context = self.decimal.Context
2150n/a localcontext = self.decimal.localcontext
2151n/a InvalidOperation = self.decimal.InvalidOperation
2152n/a DivisionByZero = self.decimal.DivisionByZero
2153n/a Overflow = self.decimal.Overflow
2154n/a Underflow = self.decimal.Underflow
2155n/a Subnormal = self.decimal.Subnormal
2156n/a Inexact = self.decimal.Inexact
2157n/a Rounded = self.decimal.Rounded
2158n/a Clamped = self.decimal.Clamped
2159n/a
2160n/a with localcontext(Context()) as c:
2161n/a c.prec = 7
2162n/a c.Emax = 999
2163n/a c.Emin = -999
2164n/a
2165n/a x = Decimal("111")
2166n/a y = Decimal("1e9999")
2167n/a z = Decimal("1e-9999")
2168n/a
2169n/a ##### Unary functions
2170n/a c.clear_flags()
2171n/a self.assertEqual(str(x.exp(context=None)), '1.609487E+48')
2172n/a self.assertTrue(c.flags[Inexact])
2173n/a self.assertTrue(c.flags[Rounded])
2174n/a c.clear_flags()
2175n/a self.assertRaises(Overflow, y.exp, context=None)
2176n/a self.assertTrue(c.flags[Overflow])
2177n/a
2178n/a self.assertIs(z.is_normal(context=None), False)
2179n/a self.assertIs(z.is_subnormal(context=None), True)
2180n/a
2181n/a c.clear_flags()
2182n/a self.assertEqual(str(x.ln(context=None)), '4.709530')
2183n/a self.assertTrue(c.flags[Inexact])
2184n/a self.assertTrue(c.flags[Rounded])
2185n/a c.clear_flags()
2186n/a self.assertRaises(InvalidOperation, Decimal(-1).ln, context=None)
2187n/a self.assertTrue(c.flags[InvalidOperation])
2188n/a
2189n/a c.clear_flags()
2190n/a self.assertEqual(str(x.log10(context=None)), '2.045323')
2191n/a self.assertTrue(c.flags[Inexact])
2192n/a self.assertTrue(c.flags[Rounded])
2193n/a c.clear_flags()
2194n/a self.assertRaises(InvalidOperation, Decimal(-1).log10, context=None)
2195n/a self.assertTrue(c.flags[InvalidOperation])
2196n/a
2197n/a c.clear_flags()
2198n/a self.assertEqual(str(x.logb(context=None)), '2')
2199n/a self.assertRaises(DivisionByZero, Decimal(0).logb, context=None)
2200n/a self.assertTrue(c.flags[DivisionByZero])
2201n/a
2202n/a c.clear_flags()
2203n/a self.assertEqual(str(x.logical_invert(context=None)), '1111000')
2204n/a self.assertRaises(InvalidOperation, y.logical_invert, context=None)
2205n/a self.assertTrue(c.flags[InvalidOperation])
2206n/a
2207n/a c.clear_flags()
2208n/a self.assertEqual(str(y.next_minus(context=None)), '9.999999E+999')
2209n/a self.assertRaises(InvalidOperation, Decimal('sNaN').next_minus, context=None)
2210n/a self.assertTrue(c.flags[InvalidOperation])
2211n/a
2212n/a c.clear_flags()
2213n/a self.assertEqual(str(y.next_plus(context=None)), 'Infinity')
2214n/a self.assertRaises(InvalidOperation, Decimal('sNaN').next_plus, context=None)
2215n/a self.assertTrue(c.flags[InvalidOperation])
2216n/a
2217n/a c.clear_flags()
2218n/a self.assertEqual(str(z.normalize(context=None)), '0')
2219n/a self.assertRaises(Overflow, y.normalize, context=None)
2220n/a self.assertTrue(c.flags[Overflow])
2221n/a
2222n/a self.assertEqual(str(z.number_class(context=None)), '+Subnormal')
2223n/a
2224n/a c.clear_flags()
2225n/a self.assertEqual(str(z.sqrt(context=None)), '0E-1005')
2226n/a self.assertTrue(c.flags[Clamped])
2227n/a self.assertTrue(c.flags[Inexact])
2228n/a self.assertTrue(c.flags[Rounded])
2229n/a self.assertTrue(c.flags[Subnormal])
2230n/a self.assertTrue(c.flags[Underflow])
2231n/a c.clear_flags()
2232n/a self.assertRaises(Overflow, y.sqrt, context=None)
2233n/a self.assertTrue(c.flags[Overflow])
2234n/a
2235n/a c.capitals = 0
2236n/a self.assertEqual(str(z.to_eng_string(context=None)), '1e-9999')
2237n/a c.capitals = 1
2238n/a
2239n/a
2240n/a ##### Binary functions
2241n/a c.clear_flags()
2242n/a ans = str(x.compare(Decimal('Nan891287828'), context=None))
2243n/a self.assertEqual(ans, 'NaN1287828')
2244n/a self.assertRaises(InvalidOperation, x.compare, Decimal('sNaN'), context=None)
2245n/a self.assertTrue(c.flags[InvalidOperation])
2246n/a
2247n/a c.clear_flags()
2248n/a ans = str(x.compare_signal(8224, context=None))
2249n/a self.assertEqual(ans, '-1')
2250n/a self.assertRaises(InvalidOperation, x.compare_signal, Decimal('NaN'), context=None)
2251n/a self.assertTrue(c.flags[InvalidOperation])
2252n/a
2253n/a c.clear_flags()
2254n/a ans = str(x.logical_and(101, context=None))
2255n/a self.assertEqual(ans, '101')
2256n/a self.assertRaises(InvalidOperation, x.logical_and, 123, context=None)
2257n/a self.assertTrue(c.flags[InvalidOperation])
2258n/a
2259n/a c.clear_flags()
2260n/a ans = str(x.logical_or(101, context=None))
2261n/a self.assertEqual(ans, '111')
2262n/a self.assertRaises(InvalidOperation, x.logical_or, 123, context=None)
2263n/a self.assertTrue(c.flags[InvalidOperation])
2264n/a
2265n/a c.clear_flags()
2266n/a ans = str(x.logical_xor(101, context=None))
2267n/a self.assertEqual(ans, '10')
2268n/a self.assertRaises(InvalidOperation, x.logical_xor, 123, context=None)
2269n/a self.assertTrue(c.flags[InvalidOperation])
2270n/a
2271n/a c.clear_flags()
2272n/a ans = str(x.max(101, context=None))
2273n/a self.assertEqual(ans, '111')
2274n/a self.assertRaises(InvalidOperation, x.max, Decimal('sNaN'), context=None)
2275n/a self.assertTrue(c.flags[InvalidOperation])
2276n/a
2277n/a c.clear_flags()
2278n/a ans = str(x.max_mag(101, context=None))
2279n/a self.assertEqual(ans, '111')
2280n/a self.assertRaises(InvalidOperation, x.max_mag, Decimal('sNaN'), context=None)
2281n/a self.assertTrue(c.flags[InvalidOperation])
2282n/a
2283n/a c.clear_flags()
2284n/a ans = str(x.min(101, context=None))
2285n/a self.assertEqual(ans, '101')
2286n/a self.assertRaises(InvalidOperation, x.min, Decimal('sNaN'), context=None)
2287n/a self.assertTrue(c.flags[InvalidOperation])
2288n/a
2289n/a c.clear_flags()
2290n/a ans = str(x.min_mag(101, context=None))
2291n/a self.assertEqual(ans, '101')
2292n/a self.assertRaises(InvalidOperation, x.min_mag, Decimal('sNaN'), context=None)
2293n/a self.assertTrue(c.flags[InvalidOperation])
2294n/a
2295n/a c.clear_flags()
2296n/a ans = str(x.remainder_near(101, context=None))
2297n/a self.assertEqual(ans, '10')
2298n/a self.assertRaises(InvalidOperation, y.remainder_near, 101, context=None)
2299n/a self.assertTrue(c.flags[InvalidOperation])
2300n/a
2301n/a c.clear_flags()
2302n/a ans = str(x.rotate(2, context=None))
2303n/a self.assertEqual(ans, '11100')
2304n/a self.assertRaises(InvalidOperation, x.rotate, 101, context=None)
2305n/a self.assertTrue(c.flags[InvalidOperation])
2306n/a
2307n/a c.clear_flags()
2308n/a ans = str(x.scaleb(7, context=None))
2309n/a self.assertEqual(ans, '1.11E+9')
2310n/a self.assertRaises(InvalidOperation, x.scaleb, 10000, context=None)
2311n/a self.assertTrue(c.flags[InvalidOperation])
2312n/a
2313n/a c.clear_flags()
2314n/a ans = str(x.shift(2, context=None))
2315n/a self.assertEqual(ans, '11100')
2316n/a self.assertRaises(InvalidOperation, x.shift, 10000, context=None)
2317n/a self.assertTrue(c.flags[InvalidOperation])
2318n/a
2319n/a
2320n/a ##### Ternary functions
2321n/a c.clear_flags()
2322n/a ans = str(x.fma(2, 3, context=None))
2323n/a self.assertEqual(ans, '225')
2324n/a self.assertRaises(Overflow, x.fma, Decimal('1e9999'), 3, context=None)
2325n/a self.assertTrue(c.flags[Overflow])
2326n/a
2327n/a
2328n/a ##### Special cases
2329n/a c.rounding = ROUND_HALF_EVEN
2330n/a ans = str(Decimal('1.5').to_integral(rounding=None, context=None))
2331n/a self.assertEqual(ans, '2')
2332n/a c.rounding = ROUND_DOWN
2333n/a ans = str(Decimal('1.5').to_integral(rounding=None, context=None))
2334n/a self.assertEqual(ans, '1')
2335n/a ans = str(Decimal('1.5').to_integral(rounding=ROUND_UP, context=None))
2336n/a self.assertEqual(ans, '2')
2337n/a c.clear_flags()
2338n/a self.assertRaises(InvalidOperation, Decimal('sNaN').to_integral, context=None)
2339n/a self.assertTrue(c.flags[InvalidOperation])
2340n/a
2341n/a c.rounding = ROUND_HALF_EVEN
2342n/a ans = str(Decimal('1.5').to_integral_value(rounding=None, context=None))
2343n/a self.assertEqual(ans, '2')
2344n/a c.rounding = ROUND_DOWN
2345n/a ans = str(Decimal('1.5').to_integral_value(rounding=None, context=None))
2346n/a self.assertEqual(ans, '1')
2347n/a ans = str(Decimal('1.5').to_integral_value(rounding=ROUND_UP, context=None))
2348n/a self.assertEqual(ans, '2')
2349n/a c.clear_flags()
2350n/a self.assertRaises(InvalidOperation, Decimal('sNaN').to_integral_value, context=None)
2351n/a self.assertTrue(c.flags[InvalidOperation])
2352n/a
2353n/a c.rounding = ROUND_HALF_EVEN
2354n/a ans = str(Decimal('1.5').to_integral_exact(rounding=None, context=None))
2355n/a self.assertEqual(ans, '2')
2356n/a c.rounding = ROUND_DOWN
2357n/a ans = str(Decimal('1.5').to_integral_exact(rounding=None, context=None))
2358n/a self.assertEqual(ans, '1')
2359n/a ans = str(Decimal('1.5').to_integral_exact(rounding=ROUND_UP, context=None))
2360n/a self.assertEqual(ans, '2')
2361n/a c.clear_flags()
2362n/a self.assertRaises(InvalidOperation, Decimal('sNaN').to_integral_exact, context=None)
2363n/a self.assertTrue(c.flags[InvalidOperation])
2364n/a
2365n/a c.rounding = ROUND_UP
2366n/a ans = str(Decimal('1.50001').quantize(exp=Decimal('1e-3'), rounding=None, context=None))
2367n/a self.assertEqual(ans, '1.501')
2368n/a c.rounding = ROUND_DOWN
2369n/a ans = str(Decimal('1.50001').quantize(exp=Decimal('1e-3'), rounding=None, context=None))
2370n/a self.assertEqual(ans, '1.500')
2371n/a ans = str(Decimal('1.50001').quantize(exp=Decimal('1e-3'), rounding=ROUND_UP, context=None))
2372n/a self.assertEqual(ans, '1.501')
2373n/a c.clear_flags()
2374n/a self.assertRaises(InvalidOperation, y.quantize, Decimal('1e-10'), rounding=ROUND_UP, context=None)
2375n/a self.assertTrue(c.flags[InvalidOperation])
2376n/a
2377n/a with localcontext(Context()) as context:
2378n/a context.prec = 7
2379n/a context.Emax = 999
2380n/a context.Emin = -999
2381n/a with localcontext(ctx=None) as c:
2382n/a self.assertEqual(c.prec, 7)
2383n/a self.assertEqual(c.Emax, 999)
2384n/a self.assertEqual(c.Emin, -999)
2385n/a
2386n/a def test_conversions_from_int(self):
2387n/a # Check that methods taking a second Decimal argument will
2388n/a # always accept an integer in place of a Decimal.
2389n/a Decimal = self.decimal.Decimal
2390n/a
2391n/a self.assertEqual(Decimal(4).compare(3),
2392n/a Decimal(4).compare(Decimal(3)))
2393n/a self.assertEqual(Decimal(4).compare_signal(3),
2394n/a Decimal(4).compare_signal(Decimal(3)))
2395n/a self.assertEqual(Decimal(4).compare_total(3),
2396n/a Decimal(4).compare_total(Decimal(3)))
2397n/a self.assertEqual(Decimal(4).compare_total_mag(3),
2398n/a Decimal(4).compare_total_mag(Decimal(3)))
2399n/a self.assertEqual(Decimal(10101).logical_and(1001),
2400n/a Decimal(10101).logical_and(Decimal(1001)))
2401n/a self.assertEqual(Decimal(10101).logical_or(1001),
2402n/a Decimal(10101).logical_or(Decimal(1001)))
2403n/a self.assertEqual(Decimal(10101).logical_xor(1001),
2404n/a Decimal(10101).logical_xor(Decimal(1001)))
2405n/a self.assertEqual(Decimal(567).max(123),
2406n/a Decimal(567).max(Decimal(123)))
2407n/a self.assertEqual(Decimal(567).max_mag(123),
2408n/a Decimal(567).max_mag(Decimal(123)))
2409n/a self.assertEqual(Decimal(567).min(123),
2410n/a Decimal(567).min(Decimal(123)))
2411n/a self.assertEqual(Decimal(567).min_mag(123),
2412n/a Decimal(567).min_mag(Decimal(123)))
2413n/a self.assertEqual(Decimal(567).next_toward(123),
2414n/a Decimal(567).next_toward(Decimal(123)))
2415n/a self.assertEqual(Decimal(1234).quantize(100),
2416n/a Decimal(1234).quantize(Decimal(100)))
2417n/a self.assertEqual(Decimal(768).remainder_near(1234),
2418n/a Decimal(768).remainder_near(Decimal(1234)))
2419n/a self.assertEqual(Decimal(123).rotate(1),
2420n/a Decimal(123).rotate(Decimal(1)))
2421n/a self.assertEqual(Decimal(1234).same_quantum(1000),
2422n/a Decimal(1234).same_quantum(Decimal(1000)))
2423n/a self.assertEqual(Decimal('9.123').scaleb(-100),
2424n/a Decimal('9.123').scaleb(Decimal(-100)))
2425n/a self.assertEqual(Decimal(456).shift(-1),
2426n/a Decimal(456).shift(Decimal(-1)))
2427n/a
2428n/a self.assertEqual(Decimal(-12).fma(Decimal(45), 67),
2429n/a Decimal(-12).fma(Decimal(45), Decimal(67)))
2430n/a self.assertEqual(Decimal(-12).fma(45, 67),
2431n/a Decimal(-12).fma(Decimal(45), Decimal(67)))
2432n/a self.assertEqual(Decimal(-12).fma(45, Decimal(67)),
2433n/a Decimal(-12).fma(Decimal(45), Decimal(67)))
2434n/a
2435n/aclass CUsabilityTest(UsabilityTest):
2436n/a decimal = C
2437n/aclass PyUsabilityTest(UsabilityTest):
2438n/a decimal = P
2439n/a
2440n/aclass PythonAPItests(unittest.TestCase):
2441n/a
2442n/a def test_abc(self):
2443n/a Decimal = self.decimal.Decimal
2444n/a
2445n/a self.assertTrue(issubclass(Decimal, numbers.Number))
2446n/a self.assertFalse(issubclass(Decimal, numbers.Real))
2447n/a self.assertIsInstance(Decimal(0), numbers.Number)
2448n/a self.assertNotIsInstance(Decimal(0), numbers.Real)
2449n/a
2450n/a def test_pickle(self):
2451n/a for proto in range(pickle.HIGHEST_PROTOCOL + 1):
2452n/a Decimal = self.decimal.Decimal
2453n/a
2454n/a savedecimal = sys.modules['decimal']
2455n/a
2456n/a # Round trip
2457n/a sys.modules['decimal'] = self.decimal
2458n/a d = Decimal('-3.141590000')
2459n/a p = pickle.dumps(d, proto)
2460n/a e = pickle.loads(p)
2461n/a self.assertEqual(d, e)
2462n/a
2463n/a if C:
2464n/a # Test interchangeability
2465n/a x = C.Decimal('-3.123e81723')
2466n/a y = P.Decimal('-3.123e81723')
2467n/a
2468n/a sys.modules['decimal'] = C
2469n/a sx = pickle.dumps(x, proto)
2470n/a sys.modules['decimal'] = P
2471n/a r = pickle.loads(sx)
2472n/a self.assertIsInstance(r, P.Decimal)
2473n/a self.assertEqual(r, y)
2474n/a
2475n/a sys.modules['decimal'] = P
2476n/a sy = pickle.dumps(y, proto)
2477n/a sys.modules['decimal'] = C
2478n/a r = pickle.loads(sy)
2479n/a self.assertIsInstance(r, C.Decimal)
2480n/a self.assertEqual(r, x)
2481n/a
2482n/a x = C.Decimal('-3.123e81723').as_tuple()
2483n/a y = P.Decimal('-3.123e81723').as_tuple()
2484n/a
2485n/a sys.modules['decimal'] = C
2486n/a sx = pickle.dumps(x, proto)
2487n/a sys.modules['decimal'] = P
2488n/a r = pickle.loads(sx)
2489n/a self.assertIsInstance(r, P.DecimalTuple)
2490n/a self.assertEqual(r, y)
2491n/a
2492n/a sys.modules['decimal'] = P
2493n/a sy = pickle.dumps(y, proto)
2494n/a sys.modules['decimal'] = C
2495n/a r = pickle.loads(sy)
2496n/a self.assertIsInstance(r, C.DecimalTuple)
2497n/a self.assertEqual(r, x)
2498n/a
2499n/a sys.modules['decimal'] = savedecimal
2500n/a
2501n/a def test_int(self):
2502n/a Decimal = self.decimal.Decimal
2503n/a
2504n/a for x in range(-250, 250):
2505n/a s = '%0.2f' % (x / 100.0)
2506n/a # should work the same as for floats
2507n/a self.assertEqual(int(Decimal(s)), int(float(s)))
2508n/a # should work the same as to_integral in the ROUND_DOWN mode
2509n/a d = Decimal(s)
2510n/a r = d.to_integral(ROUND_DOWN)
2511n/a self.assertEqual(Decimal(int(d)), r)
2512n/a
2513n/a self.assertRaises(ValueError, int, Decimal('-nan'))
2514n/a self.assertRaises(ValueError, int, Decimal('snan'))
2515n/a self.assertRaises(OverflowError, int, Decimal('inf'))
2516n/a self.assertRaises(OverflowError, int, Decimal('-inf'))
2517n/a
2518n/a def test_trunc(self):
2519n/a Decimal = self.decimal.Decimal
2520n/a
2521n/a for x in range(-250, 250):
2522n/a s = '%0.2f' % (x / 100.0)
2523n/a # should work the same as for floats
2524n/a self.assertEqual(int(Decimal(s)), int(float(s)))
2525n/a # should work the same as to_integral in the ROUND_DOWN mode
2526n/a d = Decimal(s)
2527n/a r = d.to_integral(ROUND_DOWN)
2528n/a self.assertEqual(Decimal(math.trunc(d)), r)
2529n/a
2530n/a def test_from_float(self):
2531n/a
2532n/a Decimal = self.decimal.Decimal
2533n/a
2534n/a class MyDecimal(Decimal):
2535n/a def __init__(self, _):
2536n/a self.x = 'y'
2537n/a
2538n/a self.assertTrue(issubclass(MyDecimal, Decimal))
2539n/a
2540n/a r = MyDecimal.from_float(0.1)
2541n/a self.assertEqual(type(r), MyDecimal)
2542n/a self.assertEqual(str(r),
2543n/a '0.1000000000000000055511151231257827021181583404541015625')
2544n/a self.assertEqual(r.x, 'y')
2545n/a
2546n/a bigint = 12345678901234567890123456789
2547n/a self.assertEqual(MyDecimal.from_float(bigint), MyDecimal(bigint))
2548n/a self.assertTrue(MyDecimal.from_float(float('nan')).is_qnan())
2549n/a self.assertTrue(MyDecimal.from_float(float('inf')).is_infinite())
2550n/a self.assertTrue(MyDecimal.from_float(float('-inf')).is_infinite())
2551n/a self.assertEqual(str(MyDecimal.from_float(float('nan'))),
2552n/a str(Decimal('NaN')))
2553n/a self.assertEqual(str(MyDecimal.from_float(float('inf'))),
2554n/a str(Decimal('Infinity')))
2555n/a self.assertEqual(str(MyDecimal.from_float(float('-inf'))),
2556n/a str(Decimal('-Infinity')))
2557n/a self.assertRaises(TypeError, MyDecimal.from_float, 'abc')
2558n/a for i in range(200):
2559n/a x = random.expovariate(0.01) * (random.random() * 2.0 - 1.0)
2560n/a self.assertEqual(x, float(MyDecimal.from_float(x))) # roundtrip
2561n/a
2562n/a def test_create_decimal_from_float(self):
2563n/a Decimal = self.decimal.Decimal
2564n/a Context = self.decimal.Context
2565n/a Inexact = self.decimal.Inexact
2566n/a
2567n/a context = Context(prec=5, rounding=ROUND_DOWN)
2568n/a self.assertEqual(
2569n/a context.create_decimal_from_float(math.pi),
2570n/a Decimal('3.1415')
2571n/a )
2572n/a context = Context(prec=5, rounding=ROUND_UP)
2573n/a self.assertEqual(
2574n/a context.create_decimal_from_float(math.pi),
2575n/a Decimal('3.1416')
2576n/a )
2577n/a context = Context(prec=5, traps=[Inexact])
2578n/a self.assertRaises(
2579n/a Inexact,
2580n/a context.create_decimal_from_float,
2581n/a math.pi
2582n/a )
2583n/a self.assertEqual(repr(context.create_decimal_from_float(-0.0)),
2584n/a "Decimal('-0')")
2585n/a self.assertEqual(repr(context.create_decimal_from_float(1.0)),
2586n/a "Decimal('1')")
2587n/a self.assertEqual(repr(context.create_decimal_from_float(10)),
2588n/a "Decimal('10')")
2589n/a
2590n/a def test_quantize(self):
2591n/a Decimal = self.decimal.Decimal
2592n/a Context = self.decimal.Context
2593n/a InvalidOperation = self.decimal.InvalidOperation
2594n/a
2595n/a c = Context(Emax=99999, Emin=-99999)
2596n/a self.assertEqual(
2597n/a Decimal('7.335').quantize(Decimal('.01')),
2598n/a Decimal('7.34')
2599n/a )
2600n/a self.assertEqual(
2601n/a Decimal('7.335').quantize(Decimal('.01'), rounding=ROUND_DOWN),
2602n/a Decimal('7.33')
2603n/a )
2604n/a self.assertRaises(
2605n/a InvalidOperation,
2606n/a Decimal("10e99999").quantize, Decimal('1e100000'), context=c
2607n/a )
2608n/a
2609n/a c = Context()
2610n/a d = Decimal("0.871831e800")
2611n/a x = d.quantize(context=c, exp=Decimal("1e797"), rounding=ROUND_DOWN)
2612n/a self.assertEqual(x, Decimal('8.71E+799'))
2613n/a
2614n/a def test_complex(self):
2615n/a Decimal = self.decimal.Decimal
2616n/a
2617n/a x = Decimal("9.8182731e181273")
2618n/a self.assertEqual(x.real, x)
2619n/a self.assertEqual(x.imag, 0)
2620n/a self.assertEqual(x.conjugate(), x)
2621n/a
2622n/a x = Decimal("1")
2623n/a self.assertEqual(complex(x), complex(float(1)))
2624n/a
2625n/a self.assertRaises(AttributeError, setattr, x, 'real', 100)
2626n/a self.assertRaises(AttributeError, setattr, x, 'imag', 100)
2627n/a self.assertRaises(AttributeError, setattr, x, 'conjugate', 100)
2628n/a self.assertRaises(AttributeError, setattr, x, '__complex__', 100)
2629n/a
2630n/a def test_named_parameters(self):
2631n/a D = self.decimal.Decimal
2632n/a Context = self.decimal.Context
2633n/a localcontext = self.decimal.localcontext
2634n/a InvalidOperation = self.decimal.InvalidOperation
2635n/a Overflow = self.decimal.Overflow
2636n/a
2637n/a xc = Context()
2638n/a xc.prec = 1
2639n/a xc.Emax = 1
2640n/a xc.Emin = -1
2641n/a
2642n/a with localcontext() as c:
2643n/a c.clear_flags()
2644n/a
2645n/a self.assertEqual(D(9, xc), 9)
2646n/a self.assertEqual(D(9, context=xc), 9)
2647n/a self.assertEqual(D(context=xc, value=9), 9)
2648n/a self.assertEqual(D(context=xc), 0)
2649n/a xc.clear_flags()
2650n/a self.assertRaises(InvalidOperation, D, "xyz", context=xc)
2651n/a self.assertTrue(xc.flags[InvalidOperation])
2652n/a self.assertFalse(c.flags[InvalidOperation])
2653n/a
2654n/a xc.clear_flags()
2655n/a self.assertEqual(D(2).exp(context=xc), 7)
2656n/a self.assertRaises(Overflow, D(8).exp, context=xc)
2657n/a self.assertTrue(xc.flags[Overflow])
2658n/a self.assertFalse(c.flags[Overflow])
2659n/a
2660n/a xc.clear_flags()
2661n/a self.assertEqual(D(2).ln(context=xc), D('0.7'))
2662n/a self.assertRaises(InvalidOperation, D(-1).ln, context=xc)
2663n/a self.assertTrue(xc.flags[InvalidOperation])
2664n/a self.assertFalse(c.flags[InvalidOperation])
2665n/a
2666n/a self.assertEqual(D(0).log10(context=xc), D('-inf'))
2667n/a self.assertEqual(D(-1).next_minus(context=xc), -2)
2668n/a self.assertEqual(D(-1).next_plus(context=xc), D('-0.9'))
2669n/a self.assertEqual(D("9.73").normalize(context=xc), D('1E+1'))
2670n/a self.assertEqual(D("9999").to_integral(context=xc), 9999)
2671n/a self.assertEqual(D("-2000").to_integral_exact(context=xc), -2000)
2672n/a self.assertEqual(D("123").to_integral_value(context=xc), 123)
2673n/a self.assertEqual(D("0.0625").sqrt(context=xc), D('0.2'))
2674n/a
2675n/a self.assertEqual(D("0.0625").compare(context=xc, other=3), -1)
2676n/a xc.clear_flags()
2677n/a self.assertRaises(InvalidOperation,
2678n/a D("0").compare_signal, D('nan'), context=xc)
2679n/a self.assertTrue(xc.flags[InvalidOperation])
2680n/a self.assertFalse(c.flags[InvalidOperation])
2681n/a self.assertEqual(D("0.01").max(D('0.0101'), context=xc), D('0.0'))
2682n/a self.assertEqual(D("0.01").max(D('0.0101'), context=xc), D('0.0'))
2683n/a self.assertEqual(D("0.2").max_mag(D('-0.3'), context=xc),
2684n/a D('-0.3'))
2685n/a self.assertEqual(D("0.02").min(D('-0.03'), context=xc), D('-0.0'))
2686n/a self.assertEqual(D("0.02").min_mag(D('-0.03'), context=xc),
2687n/a D('0.0'))
2688n/a self.assertEqual(D("0.2").next_toward(D('-1'), context=xc), D('0.1'))
2689n/a xc.clear_flags()
2690n/a self.assertRaises(InvalidOperation,
2691n/a D("0.2").quantize, D('1e10'), context=xc)
2692n/a self.assertTrue(xc.flags[InvalidOperation])
2693n/a self.assertFalse(c.flags[InvalidOperation])
2694n/a self.assertEqual(D("9.99").remainder_near(D('1.5'), context=xc),
2695n/a D('-0.5'))
2696n/a
2697n/a self.assertEqual(D("9.9").fma(third=D('0.9'), context=xc, other=7),
2698n/a D('7E+1'))
2699n/a
2700n/a self.assertRaises(TypeError, D(1).is_canonical, context=xc)
2701n/a self.assertRaises(TypeError, D(1).is_finite, context=xc)
2702n/a self.assertRaises(TypeError, D(1).is_infinite, context=xc)
2703n/a self.assertRaises(TypeError, D(1).is_nan, context=xc)
2704n/a self.assertRaises(TypeError, D(1).is_qnan, context=xc)
2705n/a self.assertRaises(TypeError, D(1).is_snan, context=xc)
2706n/a self.assertRaises(TypeError, D(1).is_signed, context=xc)
2707n/a self.assertRaises(TypeError, D(1).is_zero, context=xc)
2708n/a
2709n/a self.assertFalse(D("0.01").is_normal(context=xc))
2710n/a self.assertTrue(D("0.01").is_subnormal(context=xc))
2711n/a
2712n/a self.assertRaises(TypeError, D(1).adjusted, context=xc)
2713n/a self.assertRaises(TypeError, D(1).conjugate, context=xc)
2714n/a self.assertRaises(TypeError, D(1).radix, context=xc)
2715n/a
2716n/a self.assertEqual(D(-111).logb(context=xc), 2)
2717n/a self.assertEqual(D(0).logical_invert(context=xc), 1)
2718n/a self.assertEqual(D('0.01').number_class(context=xc), '+Subnormal')
2719n/a self.assertEqual(D('0.21').to_eng_string(context=xc), '0.21')
2720n/a
2721n/a self.assertEqual(D('11').logical_and(D('10'), context=xc), 0)
2722n/a self.assertEqual(D('11').logical_or(D('10'), context=xc), 1)
2723n/a self.assertEqual(D('01').logical_xor(D('10'), context=xc), 1)
2724n/a self.assertEqual(D('23').rotate(1, context=xc), 3)
2725n/a self.assertEqual(D('23').rotate(1, context=xc), 3)
2726n/a xc.clear_flags()
2727n/a self.assertRaises(Overflow,
2728n/a D('23').scaleb, 1, context=xc)
2729n/a self.assertTrue(xc.flags[Overflow])
2730n/a self.assertFalse(c.flags[Overflow])
2731n/a self.assertEqual(D('23').shift(-1, context=xc), 0)
2732n/a
2733n/a self.assertRaises(TypeError, D.from_float, 1.1, context=xc)
2734n/a self.assertRaises(TypeError, D(0).as_tuple, context=xc)
2735n/a
2736n/a self.assertEqual(D(1).canonical(), 1)
2737n/a self.assertRaises(TypeError, D("-1").copy_abs, context=xc)
2738n/a self.assertRaises(TypeError, D("-1").copy_negate, context=xc)
2739n/a self.assertRaises(TypeError, D(1).canonical, context="x")
2740n/a self.assertRaises(TypeError, D(1).canonical, xyz="x")
2741n/a
2742n/a def test_exception_hierarchy(self):
2743n/a
2744n/a decimal = self.decimal
2745n/a DecimalException = decimal.DecimalException
2746n/a InvalidOperation = decimal.InvalidOperation
2747n/a FloatOperation = decimal.FloatOperation
2748n/a DivisionByZero = decimal.DivisionByZero
2749n/a Overflow = decimal.Overflow
2750n/a Underflow = decimal.Underflow
2751n/a Subnormal = decimal.Subnormal
2752n/a Inexact = decimal.Inexact
2753n/a Rounded = decimal.Rounded
2754n/a Clamped = decimal.Clamped
2755n/a
2756n/a self.assertTrue(issubclass(DecimalException, ArithmeticError))
2757n/a
2758n/a self.assertTrue(issubclass(InvalidOperation, DecimalException))
2759n/a self.assertTrue(issubclass(FloatOperation, DecimalException))
2760n/a self.assertTrue(issubclass(FloatOperation, TypeError))
2761n/a self.assertTrue(issubclass(DivisionByZero, DecimalException))
2762n/a self.assertTrue(issubclass(DivisionByZero, ZeroDivisionError))
2763n/a self.assertTrue(issubclass(Overflow, Rounded))
2764n/a self.assertTrue(issubclass(Overflow, Inexact))
2765n/a self.assertTrue(issubclass(Overflow, DecimalException))
2766n/a self.assertTrue(issubclass(Underflow, Inexact))
2767n/a self.assertTrue(issubclass(Underflow, Rounded))
2768n/a self.assertTrue(issubclass(Underflow, Subnormal))
2769n/a self.assertTrue(issubclass(Underflow, DecimalException))
2770n/a
2771n/a self.assertTrue(issubclass(Subnormal, DecimalException))
2772n/a self.assertTrue(issubclass(Inexact, DecimalException))
2773n/a self.assertTrue(issubclass(Rounded, DecimalException))
2774n/a self.assertTrue(issubclass(Clamped, DecimalException))
2775n/a
2776n/a self.assertTrue(issubclass(decimal.ConversionSyntax, InvalidOperation))
2777n/a self.assertTrue(issubclass(decimal.DivisionImpossible, InvalidOperation))
2778n/a self.assertTrue(issubclass(decimal.DivisionUndefined, InvalidOperation))
2779n/a self.assertTrue(issubclass(decimal.DivisionUndefined, ZeroDivisionError))
2780n/a self.assertTrue(issubclass(decimal.InvalidContext, InvalidOperation))
2781n/a
2782n/aclass CPythonAPItests(PythonAPItests):
2783n/a decimal = C
2784n/aclass PyPythonAPItests(PythonAPItests):
2785n/a decimal = P
2786n/a
2787n/aclass ContextAPItests(unittest.TestCase):
2788n/a
2789n/a def test_none_args(self):
2790n/a Context = self.decimal.Context
2791n/a InvalidOperation = self.decimal.InvalidOperation
2792n/a DivisionByZero = self.decimal.DivisionByZero
2793n/a Overflow = self.decimal.Overflow
2794n/a
2795n/a c1 = Context()
2796n/a c2 = Context(prec=None, rounding=None, Emax=None, Emin=None,
2797n/a capitals=None, clamp=None, flags=None, traps=None)
2798n/a for c in [c1, c2]:
2799n/a self.assertEqual(c.prec, 28)
2800n/a self.assertEqual(c.rounding, ROUND_HALF_EVEN)
2801n/a self.assertEqual(c.Emax, 999999)
2802n/a self.assertEqual(c.Emin, -999999)
2803n/a self.assertEqual(c.capitals, 1)
2804n/a self.assertEqual(c.clamp, 0)
2805n/a assert_signals(self, c, 'flags', [])
2806n/a assert_signals(self, c, 'traps', [InvalidOperation, DivisionByZero,
2807n/a Overflow])
2808n/a
2809n/a @cpython_only
2810n/a def test_from_legacy_strings(self):
2811n/a import _testcapi
2812n/a c = self.decimal.Context()
2813n/a
2814n/a for rnd in RoundingModes:
2815n/a c.rounding = _testcapi.unicode_legacy_string(rnd)
2816n/a self.assertEqual(c.rounding, rnd)
2817n/a
2818n/a s = _testcapi.unicode_legacy_string('')
2819n/a self.assertRaises(TypeError, setattr, c, 'rounding', s)
2820n/a
2821n/a s = _testcapi.unicode_legacy_string('ROUND_\x00UP')
2822n/a self.assertRaises(TypeError, setattr, c, 'rounding', s)
2823n/a
2824n/a def test_pickle(self):
2825n/a
2826n/a for proto in range(pickle.HIGHEST_PROTOCOL + 1):
2827n/a Context = self.decimal.Context
2828n/a
2829n/a savedecimal = sys.modules['decimal']
2830n/a
2831n/a # Round trip
2832n/a sys.modules['decimal'] = self.decimal
2833n/a c = Context()
2834n/a e = pickle.loads(pickle.dumps(c, proto))
2835n/a
2836n/a self.assertEqual(c.prec, e.prec)
2837n/a self.assertEqual(c.Emin, e.Emin)
2838n/a self.assertEqual(c.Emax, e.Emax)
2839n/a self.assertEqual(c.rounding, e.rounding)
2840n/a self.assertEqual(c.capitals, e.capitals)
2841n/a self.assertEqual(c.clamp, e.clamp)
2842n/a self.assertEqual(c.flags, e.flags)
2843n/a self.assertEqual(c.traps, e.traps)
2844n/a
2845n/a # Test interchangeability
2846n/a combinations = [(C, P), (P, C)] if C else [(P, P)]
2847n/a for dumper, loader in combinations:
2848n/a for ri, _ in enumerate(RoundingModes):
2849n/a for fi, _ in enumerate(OrderedSignals[dumper]):
2850n/a for ti, _ in enumerate(OrderedSignals[dumper]):
2851n/a
2852n/a prec = random.randrange(1, 100)
2853n/a emin = random.randrange(-100, 0)
2854n/a emax = random.randrange(1, 100)
2855n/a caps = random.randrange(2)
2856n/a clamp = random.randrange(2)
2857n/a
2858n/a # One module dumps
2859n/a sys.modules['decimal'] = dumper
2860n/a c = dumper.Context(
2861n/a prec=prec, Emin=emin, Emax=emax,
2862n/a rounding=RoundingModes[ri],
2863n/a capitals=caps, clamp=clamp,
2864n/a flags=OrderedSignals[dumper][:fi],
2865n/a traps=OrderedSignals[dumper][:ti]
2866n/a )
2867n/a s = pickle.dumps(c, proto)
2868n/a
2869n/a # The other module loads
2870n/a sys.modules['decimal'] = loader
2871n/a d = pickle.loads(s)
2872n/a self.assertIsInstance(d, loader.Context)
2873n/a
2874n/a self.assertEqual(d.prec, prec)
2875n/a self.assertEqual(d.Emin, emin)
2876n/a self.assertEqual(d.Emax, emax)
2877n/a self.assertEqual(d.rounding, RoundingModes[ri])
2878n/a self.assertEqual(d.capitals, caps)
2879n/a self.assertEqual(d.clamp, clamp)
2880n/a assert_signals(self, d, 'flags', OrderedSignals[loader][:fi])
2881n/a assert_signals(self, d, 'traps', OrderedSignals[loader][:ti])
2882n/a
2883n/a sys.modules['decimal'] = savedecimal
2884n/a
2885n/a def test_equality_with_other_types(self):
2886n/a Decimal = self.decimal.Decimal
2887n/a
2888n/a self.assertIn(Decimal(10), ['a', 1.0, Decimal(10), (1,2), {}])
2889n/a self.assertNotIn(Decimal(10), ['a', 1.0, (1,2), {}])
2890n/a
2891n/a def test_copy(self):
2892n/a # All copies should be deep
2893n/a Decimal = self.decimal.Decimal
2894n/a Context = self.decimal.Context
2895n/a
2896n/a c = Context()
2897n/a d = c.copy()
2898n/a self.assertNotEqual(id(c), id(d))
2899n/a self.assertNotEqual(id(c.flags), id(d.flags))
2900n/a self.assertNotEqual(id(c.traps), id(d.traps))
2901n/a k1 = set(c.flags.keys())
2902n/a k2 = set(d.flags.keys())
2903n/a self.assertEqual(k1, k2)
2904n/a self.assertEqual(c.flags, d.flags)
2905n/a
2906n/a def test__clamp(self):
2907n/a # In Python 3.2, the private attribute `_clamp` was made
2908n/a # public (issue 8540), with the old `_clamp` becoming a
2909n/a # property wrapping `clamp`. For the duration of Python 3.2
2910n/a # only, the attribute should be gettable/settable via both
2911n/a # `clamp` and `_clamp`; in Python 3.3, `_clamp` should be
2912n/a # removed.
2913n/a Context = self.decimal.Context
2914n/a c = Context()
2915n/a self.assertRaises(AttributeError, getattr, c, '_clamp')
2916n/a
2917n/a def test_abs(self):
2918n/a Decimal = self.decimal.Decimal
2919n/a Context = self.decimal.Context
2920n/a
2921n/a c = Context()
2922n/a d = c.abs(Decimal(-1))
2923n/a self.assertEqual(c.abs(-1), d)
2924n/a self.assertRaises(TypeError, c.abs, '-1')
2925n/a
2926n/a def test_add(self):
2927n/a Decimal = self.decimal.Decimal
2928n/a Context = self.decimal.Context
2929n/a
2930n/a c = Context()
2931n/a d = c.add(Decimal(1), Decimal(1))
2932n/a self.assertEqual(c.add(1, 1), d)
2933n/a self.assertEqual(c.add(Decimal(1), 1), d)
2934n/a self.assertEqual(c.add(1, Decimal(1)), d)
2935n/a self.assertRaises(TypeError, c.add, '1', 1)
2936n/a self.assertRaises(TypeError, c.add, 1, '1')
2937n/a
2938n/a def test_compare(self):
2939n/a Decimal = self.decimal.Decimal
2940n/a Context = self.decimal.Context
2941n/a
2942n/a c = Context()
2943n/a d = c.compare(Decimal(1), Decimal(1))
2944n/a self.assertEqual(c.compare(1, 1), d)
2945n/a self.assertEqual(c.compare(Decimal(1), 1), d)
2946n/a self.assertEqual(c.compare(1, Decimal(1)), d)
2947n/a self.assertRaises(TypeError, c.compare, '1', 1)
2948n/a self.assertRaises(TypeError, c.compare, 1, '1')
2949n/a
2950n/a def test_compare_signal(self):
2951n/a Decimal = self.decimal.Decimal
2952n/a Context = self.decimal.Context
2953n/a
2954n/a c = Context()
2955n/a d = c.compare_signal(Decimal(1), Decimal(1))
2956n/a self.assertEqual(c.compare_signal(1, 1), d)
2957n/a self.assertEqual(c.compare_signal(Decimal(1), 1), d)
2958n/a self.assertEqual(c.compare_signal(1, Decimal(1)), d)
2959n/a self.assertRaises(TypeError, c.compare_signal, '1', 1)
2960n/a self.assertRaises(TypeError, c.compare_signal, 1, '1')
2961n/a
2962n/a def test_compare_total(self):
2963n/a Decimal = self.decimal.Decimal
2964n/a Context = self.decimal.Context
2965n/a
2966n/a c = Context()
2967n/a d = c.compare_total(Decimal(1), Decimal(1))
2968n/a self.assertEqual(c.compare_total(1, 1), d)
2969n/a self.assertEqual(c.compare_total(Decimal(1), 1), d)
2970n/a self.assertEqual(c.compare_total(1, Decimal(1)), d)
2971n/a self.assertRaises(TypeError, c.compare_total, '1', 1)
2972n/a self.assertRaises(TypeError, c.compare_total, 1, '1')
2973n/a
2974n/a def test_compare_total_mag(self):
2975n/a Decimal = self.decimal.Decimal
2976n/a Context = self.decimal.Context
2977n/a
2978n/a c = Context()
2979n/a d = c.compare_total_mag(Decimal(1), Decimal(1))
2980n/a self.assertEqual(c.compare_total_mag(1, 1), d)
2981n/a self.assertEqual(c.compare_total_mag(Decimal(1), 1), d)
2982n/a self.assertEqual(c.compare_total_mag(1, Decimal(1)), d)
2983n/a self.assertRaises(TypeError, c.compare_total_mag, '1', 1)
2984n/a self.assertRaises(TypeError, c.compare_total_mag, 1, '1')
2985n/a
2986n/a def test_copy_abs(self):
2987n/a Decimal = self.decimal.Decimal
2988n/a Context = self.decimal.Context
2989n/a
2990n/a c = Context()
2991n/a d = c.copy_abs(Decimal(-1))
2992n/a self.assertEqual(c.copy_abs(-1), d)
2993n/a self.assertRaises(TypeError, c.copy_abs, '-1')
2994n/a
2995n/a def test_copy_decimal(self):
2996n/a Decimal = self.decimal.Decimal
2997n/a Context = self.decimal.Context
2998n/a
2999n/a c = Context()
3000n/a d = c.copy_decimal(Decimal(-1))
3001n/a self.assertEqual(c.copy_decimal(-1), d)
3002n/a self.assertRaises(TypeError, c.copy_decimal, '-1')
3003n/a
3004n/a def test_copy_negate(self):
3005n/a Decimal = self.decimal.Decimal
3006n/a Context = self.decimal.Context
3007n/a
3008n/a c = Context()
3009n/a d = c.copy_negate(Decimal(-1))
3010n/a self.assertEqual(c.copy_negate(-1), d)
3011n/a self.assertRaises(TypeError, c.copy_negate, '-1')
3012n/a
3013n/a def test_copy_sign(self):
3014n/a Decimal = self.decimal.Decimal
3015n/a Context = self.decimal.Context
3016n/a
3017n/a c = Context()
3018n/a d = c.copy_sign(Decimal(1), Decimal(-2))
3019n/a self.assertEqual(c.copy_sign(1, -2), d)
3020n/a self.assertEqual(c.copy_sign(Decimal(1), -2), d)
3021n/a self.assertEqual(c.copy_sign(1, Decimal(-2)), d)
3022n/a self.assertRaises(TypeError, c.copy_sign, '1', -2)
3023n/a self.assertRaises(TypeError, c.copy_sign, 1, '-2')
3024n/a
3025n/a def test_divide(self):
3026n/a Decimal = self.decimal.Decimal
3027n/a Context = self.decimal.Context
3028n/a
3029n/a c = Context()
3030n/a d = c.divide(Decimal(1), Decimal(2))
3031n/a self.assertEqual(c.divide(1, 2), d)
3032n/a self.assertEqual(c.divide(Decimal(1), 2), d)
3033n/a self.assertEqual(c.divide(1, Decimal(2)), d)
3034n/a self.assertRaises(TypeError, c.divide, '1', 2)
3035n/a self.assertRaises(TypeError, c.divide, 1, '2')
3036n/a
3037n/a def test_divide_int(self):
3038n/a Decimal = self.decimal.Decimal
3039n/a Context = self.decimal.Context
3040n/a
3041n/a c = Context()
3042n/a d = c.divide_int(Decimal(1), Decimal(2))
3043n/a self.assertEqual(c.divide_int(1, 2), d)
3044n/a self.assertEqual(c.divide_int(Decimal(1), 2), d)
3045n/a self.assertEqual(c.divide_int(1, Decimal(2)), d)
3046n/a self.assertRaises(TypeError, c.divide_int, '1', 2)
3047n/a self.assertRaises(TypeError, c.divide_int, 1, '2')
3048n/a
3049n/a def test_divmod(self):
3050n/a Decimal = self.decimal.Decimal
3051n/a Context = self.decimal.Context
3052n/a
3053n/a c = Context()
3054n/a d = c.divmod(Decimal(1), Decimal(2))
3055n/a self.assertEqual(c.divmod(1, 2), d)
3056n/a self.assertEqual(c.divmod(Decimal(1), 2), d)
3057n/a self.assertEqual(c.divmod(1, Decimal(2)), d)
3058n/a self.assertRaises(TypeError, c.divmod, '1', 2)
3059n/a self.assertRaises(TypeError, c.divmod, 1, '2')
3060n/a
3061n/a def test_exp(self):
3062n/a Decimal = self.decimal.Decimal
3063n/a Context = self.decimal.Context
3064n/a
3065n/a c = Context()
3066n/a d = c.exp(Decimal(10))
3067n/a self.assertEqual(c.exp(10), d)
3068n/a self.assertRaises(TypeError, c.exp, '10')
3069n/a
3070n/a def test_fma(self):
3071n/a Decimal = self.decimal.Decimal
3072n/a Context = self.decimal.Context
3073n/a
3074n/a c = Context()
3075n/a d = c.fma(Decimal(2), Decimal(3), Decimal(4))
3076n/a self.assertEqual(c.fma(2, 3, 4), d)
3077n/a self.assertEqual(c.fma(Decimal(2), 3, 4), d)
3078n/a self.assertEqual(c.fma(2, Decimal(3), 4), d)
3079n/a self.assertEqual(c.fma(2, 3, Decimal(4)), d)
3080n/a self.assertEqual(c.fma(Decimal(2), Decimal(3), 4), d)
3081n/a self.assertRaises(TypeError, c.fma, '2', 3, 4)
3082n/a self.assertRaises(TypeError, c.fma, 2, '3', 4)
3083n/a self.assertRaises(TypeError, c.fma, 2, 3, '4')
3084n/a
3085n/a # Issue 12079 for Context.fma ...
3086n/a self.assertRaises(TypeError, c.fma,
3087n/a Decimal('Infinity'), Decimal(0), "not a decimal")
3088n/a self.assertRaises(TypeError, c.fma,
3089n/a Decimal(1), Decimal('snan'), 1.222)
3090n/a # ... and for Decimal.fma.
3091n/a self.assertRaises(TypeError, Decimal('Infinity').fma,
3092n/a Decimal(0), "not a decimal")
3093n/a self.assertRaises(TypeError, Decimal(1).fma,
3094n/a Decimal('snan'), 1.222)
3095n/a
3096n/a def test_is_finite(self):
3097n/a Decimal = self.decimal.Decimal
3098n/a Context = self.decimal.Context
3099n/a
3100n/a c = Context()
3101n/a d = c.is_finite(Decimal(10))
3102n/a self.assertEqual(c.is_finite(10), d)
3103n/a self.assertRaises(TypeError, c.is_finite, '10')
3104n/a
3105n/a def test_is_infinite(self):
3106n/a Decimal = self.decimal.Decimal
3107n/a Context = self.decimal.Context
3108n/a
3109n/a c = Context()
3110n/a d = c.is_infinite(Decimal(10))
3111n/a self.assertEqual(c.is_infinite(10), d)
3112n/a self.assertRaises(TypeError, c.is_infinite, '10')
3113n/a
3114n/a def test_is_nan(self):
3115n/a Decimal = self.decimal.Decimal
3116n/a Context = self.decimal.Context
3117n/a
3118n/a c = Context()
3119n/a d = c.is_nan(Decimal(10))
3120n/a self.assertEqual(c.is_nan(10), d)
3121n/a self.assertRaises(TypeError, c.is_nan, '10')
3122n/a
3123n/a def test_is_normal(self):
3124n/a Decimal = self.decimal.Decimal
3125n/a Context = self.decimal.Context
3126n/a
3127n/a c = Context()
3128n/a d = c.is_normal(Decimal(10))
3129n/a self.assertEqual(c.is_normal(10), d)
3130n/a self.assertRaises(TypeError, c.is_normal, '10')
3131n/a
3132n/a def test_is_qnan(self):
3133n/a Decimal = self.decimal.Decimal
3134n/a Context = self.decimal.Context
3135n/a
3136n/a c = Context()
3137n/a d = c.is_qnan(Decimal(10))
3138n/a self.assertEqual(c.is_qnan(10), d)
3139n/a self.assertRaises(TypeError, c.is_qnan, '10')
3140n/a
3141n/a def test_is_signed(self):
3142n/a Decimal = self.decimal.Decimal
3143n/a Context = self.decimal.Context
3144n/a
3145n/a c = Context()
3146n/a d = c.is_signed(Decimal(10))
3147n/a self.assertEqual(c.is_signed(10), d)
3148n/a self.assertRaises(TypeError, c.is_signed, '10')
3149n/a
3150n/a def test_is_snan(self):
3151n/a Decimal = self.decimal.Decimal
3152n/a Context = self.decimal.Context
3153n/a
3154n/a c = Context()
3155n/a d = c.is_snan(Decimal(10))
3156n/a self.assertEqual(c.is_snan(10), d)
3157n/a self.assertRaises(TypeError, c.is_snan, '10')
3158n/a
3159n/a def test_is_subnormal(self):
3160n/a Decimal = self.decimal.Decimal
3161n/a Context = self.decimal.Context
3162n/a
3163n/a c = Context()
3164n/a d = c.is_subnormal(Decimal(10))
3165n/a self.assertEqual(c.is_subnormal(10), d)
3166n/a self.assertRaises(TypeError, c.is_subnormal, '10')
3167n/a
3168n/a def test_is_zero(self):
3169n/a Decimal = self.decimal.Decimal
3170n/a Context = self.decimal.Context
3171n/a
3172n/a c = Context()
3173n/a d = c.is_zero(Decimal(10))
3174n/a self.assertEqual(c.is_zero(10), d)
3175n/a self.assertRaises(TypeError, c.is_zero, '10')
3176n/a
3177n/a def test_ln(self):
3178n/a Decimal = self.decimal.Decimal
3179n/a Context = self.decimal.Context
3180n/a
3181n/a c = Context()
3182n/a d = c.ln(Decimal(10))
3183n/a self.assertEqual(c.ln(10), d)
3184n/a self.assertRaises(TypeError, c.ln, '10')
3185n/a
3186n/a def test_log10(self):
3187n/a Decimal = self.decimal.Decimal
3188n/a Context = self.decimal.Context
3189n/a
3190n/a c = Context()
3191n/a d = c.log10(Decimal(10))
3192n/a self.assertEqual(c.log10(10), d)
3193n/a self.assertRaises(TypeError, c.log10, '10')
3194n/a
3195n/a def test_logb(self):
3196n/a Decimal = self.decimal.Decimal
3197n/a Context = self.decimal.Context
3198n/a
3199n/a c = Context()
3200n/a d = c.logb(Decimal(10))
3201n/a self.assertEqual(c.logb(10), d)
3202n/a self.assertRaises(TypeError, c.logb, '10')
3203n/a
3204n/a def test_logical_and(self):
3205n/a Decimal = self.decimal.Decimal
3206n/a Context = self.decimal.Context
3207n/a
3208n/a c = Context()
3209n/a d = c.logical_and(Decimal(1), Decimal(1))
3210n/a self.assertEqual(c.logical_and(1, 1), d)
3211n/a self.assertEqual(c.logical_and(Decimal(1), 1), d)
3212n/a self.assertEqual(c.logical_and(1, Decimal(1)), d)
3213n/a self.assertRaises(TypeError, c.logical_and, '1', 1)
3214n/a self.assertRaises(TypeError, c.logical_and, 1, '1')
3215n/a
3216n/a def test_logical_invert(self):
3217n/a Decimal = self.decimal.Decimal
3218n/a Context = self.decimal.Context
3219n/a
3220n/a c = Context()
3221n/a d = c.logical_invert(Decimal(1000))
3222n/a self.assertEqual(c.logical_invert(1000), d)
3223n/a self.assertRaises(TypeError, c.logical_invert, '1000')
3224n/a
3225n/a def test_logical_or(self):
3226n/a Decimal = self.decimal.Decimal
3227n/a Context = self.decimal.Context
3228n/a
3229n/a c = Context()
3230n/a d = c.logical_or(Decimal(1), Decimal(1))
3231n/a self.assertEqual(c.logical_or(1, 1), d)
3232n/a self.assertEqual(c.logical_or(Decimal(1), 1), d)
3233n/a self.assertEqual(c.logical_or(1, Decimal(1)), d)
3234n/a self.assertRaises(TypeError, c.logical_or, '1', 1)
3235n/a self.assertRaises(TypeError, c.logical_or, 1, '1')
3236n/a
3237n/a def test_logical_xor(self):
3238n/a Decimal = self.decimal.Decimal
3239n/a Context = self.decimal.Context
3240n/a
3241n/a c = Context()
3242n/a d = c.logical_xor(Decimal(1), Decimal(1))
3243n/a self.assertEqual(c.logical_xor(1, 1), d)
3244n/a self.assertEqual(c.logical_xor(Decimal(1), 1), d)
3245n/a self.assertEqual(c.logical_xor(1, Decimal(1)), d)
3246n/a self.assertRaises(TypeError, c.logical_xor, '1', 1)
3247n/a self.assertRaises(TypeError, c.logical_xor, 1, '1')
3248n/a
3249n/a def test_max(self):
3250n/a Decimal = self.decimal.Decimal
3251n/a Context = self.decimal.Context
3252n/a
3253n/a c = Context()
3254n/a d = c.max(Decimal(1), Decimal(2))
3255n/a self.assertEqual(c.max(1, 2), d)
3256n/a self.assertEqual(c.max(Decimal(1), 2), d)
3257n/a self.assertEqual(c.max(1, Decimal(2)), d)
3258n/a self.assertRaises(TypeError, c.max, '1', 2)
3259n/a self.assertRaises(TypeError, c.max, 1, '2')
3260n/a
3261n/a def test_max_mag(self):
3262n/a Decimal = self.decimal.Decimal
3263n/a Context = self.decimal.Context
3264n/a
3265n/a c = Context()
3266n/a d = c.max_mag(Decimal(1), Decimal(2))
3267n/a self.assertEqual(c.max_mag(1, 2), d)
3268n/a self.assertEqual(c.max_mag(Decimal(1), 2), d)
3269n/a self.assertEqual(c.max_mag(1, Decimal(2)), d)
3270n/a self.assertRaises(TypeError, c.max_mag, '1', 2)
3271n/a self.assertRaises(TypeError, c.max_mag, 1, '2')
3272n/a
3273n/a def test_min(self):
3274n/a Decimal = self.decimal.Decimal
3275n/a Context = self.decimal.Context
3276n/a
3277n/a c = Context()
3278n/a d = c.min(Decimal(1), Decimal(2))
3279n/a self.assertEqual(c.min(1, 2), d)
3280n/a self.assertEqual(c.min(Decimal(1), 2), d)
3281n/a self.assertEqual(c.min(1, Decimal(2)), d)
3282n/a self.assertRaises(TypeError, c.min, '1', 2)
3283n/a self.assertRaises(TypeError, c.min, 1, '2')
3284n/a
3285n/a def test_min_mag(self):
3286n/a Decimal = self.decimal.Decimal
3287n/a Context = self.decimal.Context
3288n/a
3289n/a c = Context()
3290n/a d = c.min_mag(Decimal(1), Decimal(2))
3291n/a self.assertEqual(c.min_mag(1, 2), d)
3292n/a self.assertEqual(c.min_mag(Decimal(1), 2), d)
3293n/a self.assertEqual(c.min_mag(1, Decimal(2)), d)
3294n/a self.assertRaises(TypeError, c.min_mag, '1', 2)
3295n/a self.assertRaises(TypeError, c.min_mag, 1, '2')
3296n/a
3297n/a def test_minus(self):
3298n/a Decimal = self.decimal.Decimal
3299n/a Context = self.decimal.Context
3300n/a
3301n/a c = Context()
3302n/a d = c.minus(Decimal(10))
3303n/a self.assertEqual(c.minus(10), d)
3304n/a self.assertRaises(TypeError, c.minus, '10')
3305n/a
3306n/a def test_multiply(self):
3307n/a Decimal = self.decimal.Decimal
3308n/a Context = self.decimal.Context
3309n/a
3310n/a c = Context()
3311n/a d = c.multiply(Decimal(1), Decimal(2))
3312n/a self.assertEqual(c.multiply(1, 2), d)
3313n/a self.assertEqual(c.multiply(Decimal(1), 2), d)
3314n/a self.assertEqual(c.multiply(1, Decimal(2)), d)
3315n/a self.assertRaises(TypeError, c.multiply, '1', 2)
3316n/a self.assertRaises(TypeError, c.multiply, 1, '2')
3317n/a
3318n/a def test_next_minus(self):
3319n/a Decimal = self.decimal.Decimal
3320n/a Context = self.decimal.Context
3321n/a
3322n/a c = Context()
3323n/a d = c.next_minus(Decimal(10))
3324n/a self.assertEqual(c.next_minus(10), d)
3325n/a self.assertRaises(TypeError, c.next_minus, '10')
3326n/a
3327n/a def test_next_plus(self):
3328n/a Decimal = self.decimal.Decimal
3329n/a Context = self.decimal.Context
3330n/a
3331n/a c = Context()
3332n/a d = c.next_plus(Decimal(10))
3333n/a self.assertEqual(c.next_plus(10), d)
3334n/a self.assertRaises(TypeError, c.next_plus, '10')
3335n/a
3336n/a def test_next_toward(self):
3337n/a Decimal = self.decimal.Decimal
3338n/a Context = self.decimal.Context
3339n/a
3340n/a c = Context()
3341n/a d = c.next_toward(Decimal(1), Decimal(2))
3342n/a self.assertEqual(c.next_toward(1, 2), d)
3343n/a self.assertEqual(c.next_toward(Decimal(1), 2), d)
3344n/a self.assertEqual(c.next_toward(1, Decimal(2)), d)
3345n/a self.assertRaises(TypeError, c.next_toward, '1', 2)
3346n/a self.assertRaises(TypeError, c.next_toward, 1, '2')
3347n/a
3348n/a def test_normalize(self):
3349n/a Decimal = self.decimal.Decimal
3350n/a Context = self.decimal.Context
3351n/a
3352n/a c = Context()
3353n/a d = c.normalize(Decimal(10))
3354n/a self.assertEqual(c.normalize(10), d)
3355n/a self.assertRaises(TypeError, c.normalize, '10')
3356n/a
3357n/a def test_number_class(self):
3358n/a Decimal = self.decimal.Decimal
3359n/a Context = self.decimal.Context
3360n/a
3361n/a c = Context()
3362n/a self.assertEqual(c.number_class(123), c.number_class(Decimal(123)))
3363n/a self.assertEqual(c.number_class(0), c.number_class(Decimal(0)))
3364n/a self.assertEqual(c.number_class(-45), c.number_class(Decimal(-45)))
3365n/a
3366n/a def test_plus(self):
3367n/a Decimal = self.decimal.Decimal
3368n/a Context = self.decimal.Context
3369n/a
3370n/a c = Context()
3371n/a d = c.plus(Decimal(10))
3372n/a self.assertEqual(c.plus(10), d)
3373n/a self.assertRaises(TypeError, c.plus, '10')
3374n/a
3375n/a def test_power(self):
3376n/a Decimal = self.decimal.Decimal
3377n/a Context = self.decimal.Context
3378n/a
3379n/a c = Context()
3380n/a d = c.power(Decimal(1), Decimal(4))
3381n/a self.assertEqual(c.power(1, 4), d)
3382n/a self.assertEqual(c.power(Decimal(1), 4), d)
3383n/a self.assertEqual(c.power(1, Decimal(4)), d)
3384n/a self.assertEqual(c.power(Decimal(1), Decimal(4)), d)
3385n/a self.assertRaises(TypeError, c.power, '1', 4)
3386n/a self.assertRaises(TypeError, c.power, 1, '4')
3387n/a self.assertEqual(c.power(modulo=5, b=8, a=2), 1)
3388n/a
3389n/a def test_quantize(self):
3390n/a Decimal = self.decimal.Decimal
3391n/a Context = self.decimal.Context
3392n/a
3393n/a c = Context()
3394n/a d = c.quantize(Decimal(1), Decimal(2))
3395n/a self.assertEqual(c.quantize(1, 2), d)
3396n/a self.assertEqual(c.quantize(Decimal(1), 2), d)
3397n/a self.assertEqual(c.quantize(1, Decimal(2)), d)
3398n/a self.assertRaises(TypeError, c.quantize, '1', 2)
3399n/a self.assertRaises(TypeError, c.quantize, 1, '2')
3400n/a
3401n/a def test_remainder(self):
3402n/a Decimal = self.decimal.Decimal
3403n/a Context = self.decimal.Context
3404n/a
3405n/a c = Context()
3406n/a d = c.remainder(Decimal(1), Decimal(2))
3407n/a self.assertEqual(c.remainder(1, 2), d)
3408n/a self.assertEqual(c.remainder(Decimal(1), 2), d)
3409n/a self.assertEqual(c.remainder(1, Decimal(2)), d)
3410n/a self.assertRaises(TypeError, c.remainder, '1', 2)
3411n/a self.assertRaises(TypeError, c.remainder, 1, '2')
3412n/a
3413n/a def test_remainder_near(self):
3414n/a Decimal = self.decimal.Decimal
3415n/a Context = self.decimal.Context
3416n/a
3417n/a c = Context()
3418n/a d = c.remainder_near(Decimal(1), Decimal(2))
3419n/a self.assertEqual(c.remainder_near(1, 2), d)
3420n/a self.assertEqual(c.remainder_near(Decimal(1), 2), d)
3421n/a self.assertEqual(c.remainder_near(1, Decimal(2)), d)
3422n/a self.assertRaises(TypeError, c.remainder_near, '1', 2)
3423n/a self.assertRaises(TypeError, c.remainder_near, 1, '2')
3424n/a
3425n/a def test_rotate(self):
3426n/a Decimal = self.decimal.Decimal
3427n/a Context = self.decimal.Context
3428n/a
3429n/a c = Context()
3430n/a d = c.rotate(Decimal(1), Decimal(2))
3431n/a self.assertEqual(c.rotate(1, 2), d)
3432n/a self.assertEqual(c.rotate(Decimal(1), 2), d)
3433n/a self.assertEqual(c.rotate(1, Decimal(2)), d)
3434n/a self.assertRaises(TypeError, c.rotate, '1', 2)
3435n/a self.assertRaises(TypeError, c.rotate, 1, '2')
3436n/a
3437n/a def test_sqrt(self):
3438n/a Decimal = self.decimal.Decimal
3439n/a Context = self.decimal.Context
3440n/a
3441n/a c = Context()
3442n/a d = c.sqrt(Decimal(10))
3443n/a self.assertEqual(c.sqrt(10), d)
3444n/a self.assertRaises(TypeError, c.sqrt, '10')
3445n/a
3446n/a def test_same_quantum(self):
3447n/a Decimal = self.decimal.Decimal
3448n/a Context = self.decimal.Context
3449n/a
3450n/a c = Context()
3451n/a d = c.same_quantum(Decimal(1), Decimal(2))
3452n/a self.assertEqual(c.same_quantum(1, 2), d)
3453n/a self.assertEqual(c.same_quantum(Decimal(1), 2), d)
3454n/a self.assertEqual(c.same_quantum(1, Decimal(2)), d)
3455n/a self.assertRaises(TypeError, c.same_quantum, '1', 2)
3456n/a self.assertRaises(TypeError, c.same_quantum, 1, '2')
3457n/a
3458n/a def test_scaleb(self):
3459n/a Decimal = self.decimal.Decimal
3460n/a Context = self.decimal.Context
3461n/a
3462n/a c = Context()
3463n/a d = c.scaleb(Decimal(1), Decimal(2))
3464n/a self.assertEqual(c.scaleb(1, 2), d)
3465n/a self.assertEqual(c.scaleb(Decimal(1), 2), d)
3466n/a self.assertEqual(c.scaleb(1, Decimal(2)), d)
3467n/a self.assertRaises(TypeError, c.scaleb, '1', 2)
3468n/a self.assertRaises(TypeError, c.scaleb, 1, '2')
3469n/a
3470n/a def test_shift(self):
3471n/a Decimal = self.decimal.Decimal
3472n/a Context = self.decimal.Context
3473n/a
3474n/a c = Context()
3475n/a d = c.shift(Decimal(1), Decimal(2))
3476n/a self.assertEqual(c.shift(1, 2), d)
3477n/a self.assertEqual(c.shift(Decimal(1), 2), d)
3478n/a self.assertEqual(c.shift(1, Decimal(2)), d)
3479n/a self.assertRaises(TypeError, c.shift, '1', 2)
3480n/a self.assertRaises(TypeError, c.shift, 1, '2')
3481n/a
3482n/a def test_subtract(self):
3483n/a Decimal = self.decimal.Decimal
3484n/a Context = self.decimal.Context
3485n/a
3486n/a c = Context()
3487n/a d = c.subtract(Decimal(1), Decimal(2))
3488n/a self.assertEqual(c.subtract(1, 2), d)
3489n/a self.assertEqual(c.subtract(Decimal(1), 2), d)
3490n/a self.assertEqual(c.subtract(1, Decimal(2)), d)
3491n/a self.assertRaises(TypeError, c.subtract, '1', 2)
3492n/a self.assertRaises(TypeError, c.subtract, 1, '2')
3493n/a
3494n/a def test_to_eng_string(self):
3495n/a Decimal = self.decimal.Decimal
3496n/a Context = self.decimal.Context
3497n/a
3498n/a c = Context()
3499n/a d = c.to_eng_string(Decimal(10))
3500n/a self.assertEqual(c.to_eng_string(10), d)
3501n/a self.assertRaises(TypeError, c.to_eng_string, '10')
3502n/a
3503n/a def test_to_sci_string(self):
3504n/a Decimal = self.decimal.Decimal
3505n/a Context = self.decimal.Context
3506n/a
3507n/a c = Context()
3508n/a d = c.to_sci_string(Decimal(10))
3509n/a self.assertEqual(c.to_sci_string(10), d)
3510n/a self.assertRaises(TypeError, c.to_sci_string, '10')
3511n/a
3512n/a def test_to_integral_exact(self):
3513n/a Decimal = self.decimal.Decimal
3514n/a Context = self.decimal.Context
3515n/a
3516n/a c = Context()
3517n/a d = c.to_integral_exact(Decimal(10))
3518n/a self.assertEqual(c.to_integral_exact(10), d)
3519n/a self.assertRaises(TypeError, c.to_integral_exact, '10')
3520n/a
3521n/a def test_to_integral_value(self):
3522n/a Decimal = self.decimal.Decimal
3523n/a Context = self.decimal.Context
3524n/a
3525n/a c = Context()
3526n/a d = c.to_integral_value(Decimal(10))
3527n/a self.assertEqual(c.to_integral_value(10), d)
3528n/a self.assertRaises(TypeError, c.to_integral_value, '10')
3529n/a self.assertRaises(TypeError, c.to_integral_value, 10, 'x')
3530n/a
3531n/aclass CContextAPItests(ContextAPItests):
3532n/a decimal = C
3533n/aclass PyContextAPItests(ContextAPItests):
3534n/a decimal = P
3535n/a
3536n/aclass ContextWithStatement(unittest.TestCase):
3537n/a # Can't do these as docstrings until Python 2.6
3538n/a # as doctest can't handle __future__ statements
3539n/a
3540n/a def test_localcontext(self):
3541n/a # Use a copy of the current context in the block
3542n/a getcontext = self.decimal.getcontext
3543n/a localcontext = self.decimal.localcontext
3544n/a
3545n/a orig_ctx = getcontext()
3546n/a with localcontext() as enter_ctx:
3547n/a set_ctx = getcontext()
3548n/a final_ctx = getcontext()
3549n/a self.assertIs(orig_ctx, final_ctx, 'did not restore context correctly')
3550n/a self.assertIsNot(orig_ctx, set_ctx, 'did not copy the context')
3551n/a self.assertIs(set_ctx, enter_ctx, '__enter__ returned wrong context')
3552n/a
3553n/a def test_localcontextarg(self):
3554n/a # Use a copy of the supplied context in the block
3555n/a Context = self.decimal.Context
3556n/a getcontext = self.decimal.getcontext
3557n/a localcontext = self.decimal.localcontext
3558n/a
3559n/a localcontext = self.decimal.localcontext
3560n/a orig_ctx = getcontext()
3561n/a new_ctx = Context(prec=42)
3562n/a with localcontext(new_ctx) as enter_ctx:
3563n/a set_ctx = getcontext()
3564n/a final_ctx = getcontext()
3565n/a self.assertIs(orig_ctx, final_ctx, 'did not restore context correctly')
3566n/a self.assertEqual(set_ctx.prec, new_ctx.prec, 'did not set correct context')
3567n/a self.assertIsNot(new_ctx, set_ctx, 'did not copy the context')
3568n/a self.assertIs(set_ctx, enter_ctx, '__enter__ returned wrong context')
3569n/a
3570n/a def test_nested_with_statements(self):
3571n/a # Use a copy of the supplied context in the block
3572n/a Decimal = self.decimal.Decimal
3573n/a Context = self.decimal.Context
3574n/a getcontext = self.decimal.getcontext
3575n/a localcontext = self.decimal.localcontext
3576n/a Clamped = self.decimal.Clamped
3577n/a Overflow = self.decimal.Overflow
3578n/a
3579n/a orig_ctx = getcontext()
3580n/a orig_ctx.clear_flags()
3581n/a new_ctx = Context(Emax=384)
3582n/a with localcontext() as c1:
3583n/a self.assertEqual(c1.flags, orig_ctx.flags)
3584n/a self.assertEqual(c1.traps, orig_ctx.traps)
3585n/a c1.traps[Clamped] = True
3586n/a c1.Emin = -383
3587n/a self.assertNotEqual(orig_ctx.Emin, -383)
3588n/a self.assertRaises(Clamped, c1.create_decimal, '0e-999')
3589n/a self.assertTrue(c1.flags[Clamped])
3590n/a with localcontext(new_ctx) as c2:
3591n/a self.assertEqual(c2.flags, new_ctx.flags)
3592n/a self.assertEqual(c2.traps, new_ctx.traps)
3593n/a self.assertRaises(Overflow, c2.power, Decimal('3.4e200'), 2)
3594n/a self.assertFalse(c2.flags[Clamped])
3595n/a self.assertTrue(c2.flags[Overflow])
3596n/a del c2
3597n/a self.assertFalse(c1.flags[Overflow])
3598n/a del c1
3599n/a self.assertNotEqual(orig_ctx.Emin, -383)
3600n/a self.assertFalse(orig_ctx.flags[Clamped])
3601n/a self.assertFalse(orig_ctx.flags[Overflow])
3602n/a self.assertFalse(new_ctx.flags[Clamped])
3603n/a self.assertFalse(new_ctx.flags[Overflow])
3604n/a
3605n/a def test_with_statements_gc1(self):
3606n/a localcontext = self.decimal.localcontext
3607n/a
3608n/a with localcontext() as c1:
3609n/a del c1
3610n/a with localcontext() as c2:
3611n/a del c2
3612n/a with localcontext() as c3:
3613n/a del c3
3614n/a with localcontext() as c4:
3615n/a del c4
3616n/a
3617n/a def test_with_statements_gc2(self):
3618n/a localcontext = self.decimal.localcontext
3619n/a
3620n/a with localcontext() as c1:
3621n/a with localcontext(c1) as c2:
3622n/a del c1
3623n/a with localcontext(c2) as c3:
3624n/a del c2
3625n/a with localcontext(c3) as c4:
3626n/a del c3
3627n/a del c4
3628n/a
3629n/a def test_with_statements_gc3(self):
3630n/a Context = self.decimal.Context
3631n/a localcontext = self.decimal.localcontext
3632n/a getcontext = self.decimal.getcontext
3633n/a setcontext = self.decimal.setcontext
3634n/a
3635n/a with localcontext() as c1:
3636n/a del c1
3637n/a n1 = Context(prec=1)
3638n/a setcontext(n1)
3639n/a with localcontext(n1) as c2:
3640n/a del n1
3641n/a self.assertEqual(c2.prec, 1)
3642n/a del c2
3643n/a n2 = Context(prec=2)
3644n/a setcontext(n2)
3645n/a del n2
3646n/a self.assertEqual(getcontext().prec, 2)
3647n/a n3 = Context(prec=3)
3648n/a setcontext(n3)
3649n/a self.assertEqual(getcontext().prec, 3)
3650n/a with localcontext(n3) as c3:
3651n/a del n3
3652n/a self.assertEqual(c3.prec, 3)
3653n/a del c3
3654n/a n4 = Context(prec=4)
3655n/a setcontext(n4)
3656n/a del n4
3657n/a self.assertEqual(getcontext().prec, 4)
3658n/a with localcontext() as c4:
3659n/a self.assertEqual(c4.prec, 4)
3660n/a del c4
3661n/a
3662n/aclass CContextWithStatement(ContextWithStatement):
3663n/a decimal = C
3664n/aclass PyContextWithStatement(ContextWithStatement):
3665n/a decimal = P
3666n/a
3667n/aclass ContextFlags(unittest.TestCase):
3668n/a
3669n/a def test_flags_irrelevant(self):
3670n/a # check that the result (numeric result + flags raised) of an
3671n/a # arithmetic operation doesn't depend on the current flags
3672n/a Decimal = self.decimal.Decimal
3673n/a Context = self.decimal.Context
3674n/a Inexact = self.decimal.Inexact
3675n/a Rounded = self.decimal.Rounded
3676n/a Underflow = self.decimal.Underflow
3677n/a Clamped = self.decimal.Clamped
3678n/a Subnormal = self.decimal.Subnormal
3679n/a
3680n/a def raise_error(context, flag):
3681n/a if self.decimal == C:
3682n/a context.flags[flag] = True
3683n/a if context.traps[flag]:
3684n/a raise flag
3685n/a else:
3686n/a context._raise_error(flag)
3687n/a
3688n/a context = Context(prec=9, Emin = -425000000, Emax = 425000000,
3689n/a rounding=ROUND_HALF_EVEN, traps=[], flags=[])
3690n/a
3691n/a # operations that raise various flags, in the form (function, arglist)
3692n/a operations = [
3693n/a (context._apply, [Decimal("100E-425000010")]),
3694n/a (context.sqrt, [Decimal(2)]),
3695n/a (context.add, [Decimal("1.23456789"), Decimal("9.87654321")]),
3696n/a (context.multiply, [Decimal("1.23456789"), Decimal("9.87654321")]),
3697n/a (context.subtract, [Decimal("1.23456789"), Decimal("9.87654321")]),
3698n/a ]
3699n/a
3700n/a # try various flags individually, then a whole lot at once
3701n/a flagsets = [[Inexact], [Rounded], [Underflow], [Clamped], [Subnormal],
3702n/a [Inexact, Rounded, Underflow, Clamped, Subnormal]]
3703n/a
3704n/a for fn, args in operations:
3705n/a # find answer and flags raised using a clean context
3706n/a context.clear_flags()
3707n/a ans = fn(*args)
3708n/a flags = [k for k, v in context.flags.items() if v]
3709n/a
3710n/a for extra_flags in flagsets:
3711n/a # set flags, before calling operation
3712n/a context.clear_flags()
3713n/a for flag in extra_flags:
3714n/a raise_error(context, flag)
3715n/a new_ans = fn(*args)
3716n/a
3717n/a # flags that we expect to be set after the operation
3718n/a expected_flags = list(flags)
3719n/a for flag in extra_flags:
3720n/a if flag not in expected_flags:
3721n/a expected_flags.append(flag)
3722n/a expected_flags.sort(key=id)
3723n/a
3724n/a # flags we actually got
3725n/a new_flags = [k for k,v in context.flags.items() if v]
3726n/a new_flags.sort(key=id)
3727n/a
3728n/a self.assertEqual(ans, new_ans,
3729n/a "operation produces different answers depending on flags set: " +
3730n/a "expected %s, got %s." % (ans, new_ans))
3731n/a self.assertEqual(new_flags, expected_flags,
3732n/a "operation raises different flags depending on flags set: " +
3733n/a "expected %s, got %s" % (expected_flags, new_flags))
3734n/a
3735n/a def test_flag_comparisons(self):
3736n/a Context = self.decimal.Context
3737n/a Inexact = self.decimal.Inexact
3738n/a Rounded = self.decimal.Rounded
3739n/a
3740n/a c = Context()
3741n/a
3742n/a # Valid SignalDict
3743n/a self.assertNotEqual(c.flags, c.traps)
3744n/a self.assertNotEqual(c.traps, c.flags)
3745n/a
3746n/a c.flags = c.traps
3747n/a self.assertEqual(c.flags, c.traps)
3748n/a self.assertEqual(c.traps, c.flags)
3749n/a
3750n/a c.flags[Rounded] = True
3751n/a c.traps = c.flags
3752n/a self.assertEqual(c.flags, c.traps)
3753n/a self.assertEqual(c.traps, c.flags)
3754n/a
3755n/a d = {}
3756n/a d.update(c.flags)
3757n/a self.assertEqual(d, c.flags)
3758n/a self.assertEqual(c.flags, d)
3759n/a
3760n/a d[Inexact] = True
3761n/a self.assertNotEqual(d, c.flags)
3762n/a self.assertNotEqual(c.flags, d)
3763n/a
3764n/a # Invalid SignalDict
3765n/a d = {Inexact:False}
3766n/a self.assertNotEqual(d, c.flags)
3767n/a self.assertNotEqual(c.flags, d)
3768n/a
3769n/a d = ["xyz"]
3770n/a self.assertNotEqual(d, c.flags)
3771n/a self.assertNotEqual(c.flags, d)
3772n/a
3773n/a @requires_IEEE_754
3774n/a def test_float_operation(self):
3775n/a Decimal = self.decimal.Decimal
3776n/a FloatOperation = self.decimal.FloatOperation
3777n/a localcontext = self.decimal.localcontext
3778n/a
3779n/a with localcontext() as c:
3780n/a ##### trap is off by default
3781n/a self.assertFalse(c.traps[FloatOperation])
3782n/a
3783n/a # implicit conversion sets the flag
3784n/a c.clear_flags()
3785n/a self.assertEqual(Decimal(7.5), 7.5)
3786n/a self.assertTrue(c.flags[FloatOperation])
3787n/a
3788n/a c.clear_flags()
3789n/a self.assertEqual(c.create_decimal(7.5), 7.5)
3790n/a self.assertTrue(c.flags[FloatOperation])
3791n/a
3792n/a # explicit conversion does not set the flag
3793n/a c.clear_flags()
3794n/a x = Decimal.from_float(7.5)
3795n/a self.assertFalse(c.flags[FloatOperation])
3796n/a # comparison sets the flag
3797n/a self.assertEqual(x, 7.5)
3798n/a self.assertTrue(c.flags[FloatOperation])
3799n/a
3800n/a c.clear_flags()
3801n/a x = c.create_decimal_from_float(7.5)
3802n/a self.assertFalse(c.flags[FloatOperation])
3803n/a self.assertEqual(x, 7.5)
3804n/a self.assertTrue(c.flags[FloatOperation])
3805n/a
3806n/a ##### set the trap
3807n/a c.traps[FloatOperation] = True
3808n/a
3809n/a # implicit conversion raises
3810n/a c.clear_flags()
3811n/a self.assertRaises(FloatOperation, Decimal, 7.5)
3812n/a self.assertTrue(c.flags[FloatOperation])
3813n/a
3814n/a c.clear_flags()
3815n/a self.assertRaises(FloatOperation, c.create_decimal, 7.5)
3816n/a self.assertTrue(c.flags[FloatOperation])
3817n/a
3818n/a # explicit conversion is silent
3819n/a c.clear_flags()
3820n/a x = Decimal.from_float(7.5)
3821n/a self.assertFalse(c.flags[FloatOperation])
3822n/a
3823n/a c.clear_flags()
3824n/a x = c.create_decimal_from_float(7.5)
3825n/a self.assertFalse(c.flags[FloatOperation])
3826n/a
3827n/a def test_float_comparison(self):
3828n/a Decimal = self.decimal.Decimal
3829n/a Context = self.decimal.Context
3830n/a FloatOperation = self.decimal.FloatOperation
3831n/a localcontext = self.decimal.localcontext
3832n/a
3833n/a def assert_attr(a, b, attr, context, signal=None):
3834n/a context.clear_flags()
3835n/a f = getattr(a, attr)
3836n/a if signal == FloatOperation:
3837n/a self.assertRaises(signal, f, b)
3838n/a else:
3839n/a self.assertIs(f(b), True)
3840n/a self.assertTrue(context.flags[FloatOperation])
3841n/a
3842n/a small_d = Decimal('0.25')
3843n/a big_d = Decimal('3.0')
3844n/a small_f = 0.25
3845n/a big_f = 3.0
3846n/a
3847n/a zero_d = Decimal('0.0')
3848n/a neg_zero_d = Decimal('-0.0')
3849n/a zero_f = 0.0
3850n/a neg_zero_f = -0.0
3851n/a
3852n/a inf_d = Decimal('Infinity')
3853n/a neg_inf_d = Decimal('-Infinity')
3854n/a inf_f = float('inf')
3855n/a neg_inf_f = float('-inf')
3856n/a
3857n/a def doit(c, signal=None):
3858n/a # Order
3859n/a for attr in '__lt__', '__le__':
3860n/a assert_attr(small_d, big_f, attr, c, signal)
3861n/a
3862n/a for attr in '__gt__', '__ge__':
3863n/a assert_attr(big_d, small_f, attr, c, signal)
3864n/a
3865n/a # Equality
3866n/a assert_attr(small_d, small_f, '__eq__', c, None)
3867n/a
3868n/a assert_attr(neg_zero_d, neg_zero_f, '__eq__', c, None)
3869n/a assert_attr(neg_zero_d, zero_f, '__eq__', c, None)
3870n/a
3871n/a assert_attr(zero_d, neg_zero_f, '__eq__', c, None)
3872n/a assert_attr(zero_d, zero_f, '__eq__', c, None)
3873n/a
3874n/a assert_attr(neg_inf_d, neg_inf_f, '__eq__', c, None)
3875n/a assert_attr(inf_d, inf_f, '__eq__', c, None)
3876n/a
3877n/a # Inequality
3878n/a assert_attr(small_d, big_f, '__ne__', c, None)
3879n/a
3880n/a assert_attr(Decimal('0.1'), 0.1, '__ne__', c, None)
3881n/a
3882n/a assert_attr(neg_inf_d, inf_f, '__ne__', c, None)
3883n/a assert_attr(inf_d, neg_inf_f, '__ne__', c, None)
3884n/a
3885n/a assert_attr(Decimal('NaN'), float('nan'), '__ne__', c, None)
3886n/a
3887n/a def test_containers(c, signal=None):
3888n/a c.clear_flags()
3889n/a s = set([100.0, Decimal('100.0')])
3890n/a self.assertEqual(len(s), 1)
3891n/a self.assertTrue(c.flags[FloatOperation])
3892n/a
3893n/a c.clear_flags()
3894n/a if signal:
3895n/a self.assertRaises(signal, sorted, [1.0, Decimal('10.0')])
3896n/a else:
3897n/a s = sorted([10.0, Decimal('10.0')])
3898n/a self.assertTrue(c.flags[FloatOperation])
3899n/a
3900n/a c.clear_flags()
3901n/a b = 10.0 in [Decimal('10.0'), 1.0]
3902n/a self.assertTrue(c.flags[FloatOperation])
3903n/a
3904n/a c.clear_flags()
3905n/a b = 10.0 in {Decimal('10.0'):'a', 1.0:'b'}
3906n/a self.assertTrue(c.flags[FloatOperation])
3907n/a
3908n/a nc = Context()
3909n/a with localcontext(nc) as c:
3910n/a self.assertFalse(c.traps[FloatOperation])
3911n/a doit(c, signal=None)
3912n/a test_containers(c, signal=None)
3913n/a
3914n/a c.traps[FloatOperation] = True
3915n/a doit(c, signal=FloatOperation)
3916n/a test_containers(c, signal=FloatOperation)
3917n/a
3918n/a def test_float_operation_default(self):
3919n/a Decimal = self.decimal.Decimal
3920n/a Context = self.decimal.Context
3921n/a Inexact = self.decimal.Inexact
3922n/a FloatOperation= self.decimal.FloatOperation
3923n/a
3924n/a context = Context()
3925n/a self.assertFalse(context.flags[FloatOperation])
3926n/a self.assertFalse(context.traps[FloatOperation])
3927n/a
3928n/a context.clear_traps()
3929n/a context.traps[Inexact] = True
3930n/a context.traps[FloatOperation] = True
3931n/a self.assertTrue(context.traps[FloatOperation])
3932n/a self.assertTrue(context.traps[Inexact])
3933n/a
3934n/aclass CContextFlags(ContextFlags):
3935n/a decimal = C
3936n/aclass PyContextFlags(ContextFlags):
3937n/a decimal = P
3938n/a
3939n/aclass SpecialContexts(unittest.TestCase):
3940n/a """Test the context templates."""
3941n/a
3942n/a def test_context_templates(self):
3943n/a BasicContext = self.decimal.BasicContext
3944n/a ExtendedContext = self.decimal.ExtendedContext
3945n/a getcontext = self.decimal.getcontext
3946n/a setcontext = self.decimal.setcontext
3947n/a InvalidOperation = self.decimal.InvalidOperation
3948n/a DivisionByZero = self.decimal.DivisionByZero
3949n/a Overflow = self.decimal.Overflow
3950n/a Underflow = self.decimal.Underflow
3951n/a Clamped = self.decimal.Clamped
3952n/a
3953n/a assert_signals(self, BasicContext, 'traps',
3954n/a [InvalidOperation, DivisionByZero, Overflow, Underflow, Clamped]
3955n/a )
3956n/a
3957n/a savecontext = getcontext().copy()
3958n/a basic_context_prec = BasicContext.prec
3959n/a extended_context_prec = ExtendedContext.prec
3960n/a
3961n/a ex = None
3962n/a try:
3963n/a BasicContext.prec = ExtendedContext.prec = 441
3964n/a for template in BasicContext, ExtendedContext:
3965n/a setcontext(template)
3966n/a c = getcontext()
3967n/a self.assertIsNot(c, template)
3968n/a self.assertEqual(c.prec, 441)
3969n/a except Exception as e:
3970n/a ex = e.__class__
3971n/a finally:
3972n/a BasicContext.prec = basic_context_prec
3973n/a ExtendedContext.prec = extended_context_prec
3974n/a setcontext(savecontext)
3975n/a if ex:
3976n/a raise ex
3977n/a
3978n/a def test_default_context(self):
3979n/a DefaultContext = self.decimal.DefaultContext
3980n/a BasicContext = self.decimal.BasicContext
3981n/a ExtendedContext = self.decimal.ExtendedContext
3982n/a getcontext = self.decimal.getcontext
3983n/a setcontext = self.decimal.setcontext
3984n/a InvalidOperation = self.decimal.InvalidOperation
3985n/a DivisionByZero = self.decimal.DivisionByZero
3986n/a Overflow = self.decimal.Overflow
3987n/a
3988n/a self.assertEqual(BasicContext.prec, 9)
3989n/a self.assertEqual(ExtendedContext.prec, 9)
3990n/a
3991n/a assert_signals(self, DefaultContext, 'traps',
3992n/a [InvalidOperation, DivisionByZero, Overflow]
3993n/a )
3994n/a
3995n/a savecontext = getcontext().copy()
3996n/a default_context_prec = DefaultContext.prec
3997n/a
3998n/a ex = None
3999n/a try:
4000n/a c = getcontext()
4001n/a saveprec = c.prec
4002n/a
4003n/a DefaultContext.prec = 961
4004n/a c = getcontext()
4005n/a self.assertEqual(c.prec, saveprec)
4006n/a
4007n/a setcontext(DefaultContext)
4008n/a c = getcontext()
4009n/a self.assertIsNot(c, DefaultContext)
4010n/a self.assertEqual(c.prec, 961)
4011n/a except Exception as e:
4012n/a ex = e.__class__
4013n/a finally:
4014n/a DefaultContext.prec = default_context_prec
4015n/a setcontext(savecontext)
4016n/a if ex:
4017n/a raise ex
4018n/a
4019n/aclass CSpecialContexts(SpecialContexts):
4020n/a decimal = C
4021n/aclass PySpecialContexts(SpecialContexts):
4022n/a decimal = P
4023n/a
4024n/aclass ContextInputValidation(unittest.TestCase):
4025n/a
4026n/a def test_invalid_context(self):
4027n/a Context = self.decimal.Context
4028n/a DefaultContext = self.decimal.DefaultContext
4029n/a
4030n/a c = DefaultContext.copy()
4031n/a
4032n/a # prec, Emax
4033n/a for attr in ['prec', 'Emax']:
4034n/a setattr(c, attr, 999999)
4035n/a self.assertEqual(getattr(c, attr), 999999)
4036n/a self.assertRaises(ValueError, setattr, c, attr, -1)
4037n/a self.assertRaises(TypeError, setattr, c, attr, 'xyz')
4038n/a
4039n/a # Emin
4040n/a setattr(c, 'Emin', -999999)
4041n/a self.assertEqual(getattr(c, 'Emin'), -999999)
4042n/a self.assertRaises(ValueError, setattr, c, 'Emin', 1)
4043n/a self.assertRaises(TypeError, setattr, c, 'Emin', (1,2,3))
4044n/a
4045n/a self.assertRaises(TypeError, setattr, c, 'rounding', -1)
4046n/a self.assertRaises(TypeError, setattr, c, 'rounding', 9)
4047n/a self.assertRaises(TypeError, setattr, c, 'rounding', 1.0)
4048n/a self.assertRaises(TypeError, setattr, c, 'rounding', 'xyz')
4049n/a
4050n/a # capitals, clamp
4051n/a for attr in ['capitals', 'clamp']:
4052n/a self.assertRaises(ValueError, setattr, c, attr, -1)
4053n/a self.assertRaises(ValueError, setattr, c, attr, 2)
4054n/a self.assertRaises(TypeError, setattr, c, attr, [1,2,3])
4055n/a
4056n/a # Invalid attribute
4057n/a self.assertRaises(AttributeError, setattr, c, 'emax', 100)
4058n/a
4059n/a # Invalid signal dict
4060n/a self.assertRaises(TypeError, setattr, c, 'flags', [])
4061n/a self.assertRaises(KeyError, setattr, c, 'flags', {})
4062n/a self.assertRaises(KeyError, setattr, c, 'traps',
4063n/a {'InvalidOperation':0})
4064n/a
4065n/a # Attributes cannot be deleted
4066n/a for attr in ['prec', 'Emax', 'Emin', 'rounding', 'capitals', 'clamp',
4067n/a 'flags', 'traps']:
4068n/a self.assertRaises(AttributeError, c.__delattr__, attr)
4069n/a
4070n/a # Invalid attributes
4071n/a self.assertRaises(TypeError, getattr, c, 9)
4072n/a self.assertRaises(TypeError, setattr, c, 9)
4073n/a
4074n/a # Invalid values in constructor
4075n/a self.assertRaises(TypeError, Context, rounding=999999)
4076n/a self.assertRaises(TypeError, Context, rounding='xyz')
4077n/a self.assertRaises(ValueError, Context, clamp=2)
4078n/a self.assertRaises(ValueError, Context, capitals=-1)
4079n/a self.assertRaises(KeyError, Context, flags=["P"])
4080n/a self.assertRaises(KeyError, Context, traps=["Q"])
4081n/a
4082n/a # Type error in conversion
4083n/a self.assertRaises(TypeError, Context, flags=(0,1))
4084n/a self.assertRaises(TypeError, Context, traps=(1,0))
4085n/a
4086n/aclass CContextInputValidation(ContextInputValidation):
4087n/a decimal = C
4088n/aclass PyContextInputValidation(ContextInputValidation):
4089n/a decimal = P
4090n/a
4091n/aclass ContextSubclassing(unittest.TestCase):
4092n/a
4093n/a def test_context_subclassing(self):
4094n/a decimal = self.decimal
4095n/a Decimal = decimal.Decimal
4096n/a Context = decimal.Context
4097n/a Clamped = decimal.Clamped
4098n/a DivisionByZero = decimal.DivisionByZero
4099n/a Inexact = decimal.Inexact
4100n/a Overflow = decimal.Overflow
4101n/a Rounded = decimal.Rounded
4102n/a Subnormal = decimal.Subnormal
4103n/a Underflow = decimal.Underflow
4104n/a InvalidOperation = decimal.InvalidOperation
4105n/a
4106n/a class MyContext(Context):
4107n/a def __init__(self, prec=None, rounding=None, Emin=None, Emax=None,
4108n/a capitals=None, clamp=None, flags=None,
4109n/a traps=None):
4110n/a Context.__init__(self)
4111n/a if prec is not None:
4112n/a self.prec = prec
4113n/a if rounding is not None:
4114n/a self.rounding = rounding
4115n/a if Emin is not None:
4116n/a self.Emin = Emin
4117n/a if Emax is not None:
4118n/a self.Emax = Emax
4119n/a if capitals is not None:
4120n/a self.capitals = capitals
4121n/a if clamp is not None:
4122n/a self.clamp = clamp
4123n/a if flags is not None:
4124n/a if isinstance(flags, list):
4125n/a flags = {v:(v in flags) for v in OrderedSignals[decimal] + flags}
4126n/a self.flags = flags
4127n/a if traps is not None:
4128n/a if isinstance(traps, list):
4129n/a traps = {v:(v in traps) for v in OrderedSignals[decimal] + traps}
4130n/a self.traps = traps
4131n/a
4132n/a c = Context()
4133n/a d = MyContext()
4134n/a for attr in ('prec', 'rounding', 'Emin', 'Emax', 'capitals', 'clamp',
4135n/a 'flags', 'traps'):
4136n/a self.assertEqual(getattr(c, attr), getattr(d, attr))
4137n/a
4138n/a # prec
4139n/a self.assertRaises(ValueError, MyContext, **{'prec':-1})
4140n/a c = MyContext(prec=1)
4141n/a self.assertEqual(c.prec, 1)
4142n/a self.assertRaises(InvalidOperation, c.quantize, Decimal('9e2'), 0)
4143n/a
4144n/a # rounding
4145n/a self.assertRaises(TypeError, MyContext, **{'rounding':'XYZ'})
4146n/a c = MyContext(rounding=ROUND_DOWN, prec=1)
4147n/a self.assertEqual(c.rounding, ROUND_DOWN)
4148n/a self.assertEqual(c.plus(Decimal('9.9')), 9)
4149n/a
4150n/a # Emin
4151n/a self.assertRaises(ValueError, MyContext, **{'Emin':5})
4152n/a c = MyContext(Emin=-1, prec=1)
4153n/a self.assertEqual(c.Emin, -1)
4154n/a x = c.add(Decimal('1e-99'), Decimal('2.234e-2000'))
4155n/a self.assertEqual(x, Decimal('0.0'))
4156n/a for signal in (Inexact, Underflow, Subnormal, Rounded, Clamped):
4157n/a self.assertTrue(c.flags[signal])
4158n/a
4159n/a # Emax
4160n/a self.assertRaises(ValueError, MyContext, **{'Emax':-1})
4161n/a c = MyContext(Emax=1, prec=1)
4162n/a self.assertEqual(c.Emax, 1)
4163n/a self.assertRaises(Overflow, c.add, Decimal('1e99'), Decimal('2.234e2000'))
4164n/a if self.decimal == C:
4165n/a for signal in (Inexact, Overflow, Rounded):
4166n/a self.assertTrue(c.flags[signal])
4167n/a
4168n/a # capitals
4169n/a self.assertRaises(ValueError, MyContext, **{'capitals':-1})
4170n/a c = MyContext(capitals=0)
4171n/a self.assertEqual(c.capitals, 0)
4172n/a x = c.create_decimal('1E222')
4173n/a self.assertEqual(c.to_sci_string(x), '1e+222')
4174n/a
4175n/a # clamp
4176n/a self.assertRaises(ValueError, MyContext, **{'clamp':2})
4177n/a c = MyContext(clamp=1, Emax=99)
4178n/a self.assertEqual(c.clamp, 1)
4179n/a x = c.plus(Decimal('1e99'))
4180n/a self.assertEqual(str(x), '1.000000000000000000000000000E+99')
4181n/a
4182n/a # flags
4183n/a self.assertRaises(TypeError, MyContext, **{'flags':'XYZ'})
4184n/a c = MyContext(flags=[Rounded, DivisionByZero])
4185n/a for signal in (Rounded, DivisionByZero):
4186n/a self.assertTrue(c.flags[signal])
4187n/a c.clear_flags()
4188n/a for signal in OrderedSignals[decimal]:
4189n/a self.assertFalse(c.flags[signal])
4190n/a
4191n/a # traps
4192n/a self.assertRaises(TypeError, MyContext, **{'traps':'XYZ'})
4193n/a c = MyContext(traps=[Rounded, DivisionByZero])
4194n/a for signal in (Rounded, DivisionByZero):
4195n/a self.assertTrue(c.traps[signal])
4196n/a c.clear_traps()
4197n/a for signal in OrderedSignals[decimal]:
4198n/a self.assertFalse(c.traps[signal])
4199n/a
4200n/aclass CContextSubclassing(ContextSubclassing):
4201n/a decimal = C
4202n/aclass PyContextSubclassing(ContextSubclassing):
4203n/a decimal = P
4204n/a
4205n/a@skip_if_extra_functionality
4206n/aclass CheckAttributes(unittest.TestCase):
4207n/a
4208n/a def test_module_attributes(self):
4209n/a
4210n/a # Architecture dependent context limits
4211n/a self.assertEqual(C.MAX_PREC, P.MAX_PREC)
4212n/a self.assertEqual(C.MAX_EMAX, P.MAX_EMAX)
4213n/a self.assertEqual(C.MIN_EMIN, P.MIN_EMIN)
4214n/a self.assertEqual(C.MIN_ETINY, P.MIN_ETINY)
4215n/a
4216n/a self.assertTrue(C.HAVE_THREADS is True or C.HAVE_THREADS is False)
4217n/a self.assertTrue(P.HAVE_THREADS is True or P.HAVE_THREADS is False)
4218n/a
4219n/a self.assertEqual(C.__version__, P.__version__)
4220n/a
4221n/a self.assertEqual(dir(C), dir(P))
4222n/a
4223n/a def test_context_attributes(self):
4224n/a
4225n/a x = [s for s in dir(C.Context()) if '__' in s or not s.startswith('_')]
4226n/a y = [s for s in dir(P.Context()) if '__' in s or not s.startswith('_')]
4227n/a self.assertEqual(set(x) - set(y), set())
4228n/a
4229n/a def test_decimal_attributes(self):
4230n/a
4231n/a x = [s for s in dir(C.Decimal(9)) if '__' in s or not s.startswith('_')]
4232n/a y = [s for s in dir(C.Decimal(9)) if '__' in s or not s.startswith('_')]
4233n/a self.assertEqual(set(x) - set(y), set())
4234n/a
4235n/aclass Coverage(unittest.TestCase):
4236n/a
4237n/a def test_adjusted(self):
4238n/a Decimal = self.decimal.Decimal
4239n/a
4240n/a self.assertEqual(Decimal('1234e9999').adjusted(), 10002)
4241n/a # XXX raise?
4242n/a self.assertEqual(Decimal('nan').adjusted(), 0)
4243n/a self.assertEqual(Decimal('inf').adjusted(), 0)
4244n/a
4245n/a def test_canonical(self):
4246n/a Decimal = self.decimal.Decimal
4247n/a getcontext = self.decimal.getcontext
4248n/a
4249n/a x = Decimal(9).canonical()
4250n/a self.assertEqual(x, 9)
4251n/a
4252n/a c = getcontext()
4253n/a x = c.canonical(Decimal(9))
4254n/a self.assertEqual(x, 9)
4255n/a
4256n/a def test_context_repr(self):
4257n/a c = self.decimal.DefaultContext.copy()
4258n/a
4259n/a c.prec = 425000000
4260n/a c.Emax = 425000000
4261n/a c.Emin = -425000000
4262n/a c.rounding = ROUND_HALF_DOWN
4263n/a c.capitals = 0
4264n/a c.clamp = 1
4265n/a for sig in OrderedSignals[self.decimal]:
4266n/a c.flags[sig] = False
4267n/a c.traps[sig] = False
4268n/a
4269n/a s = c.__repr__()
4270n/a t = "Context(prec=425000000, rounding=ROUND_HALF_DOWN, " \
4271n/a "Emin=-425000000, Emax=425000000, capitals=0, clamp=1, " \
4272n/a "flags=[], traps=[])"
4273n/a self.assertEqual(s, t)
4274n/a
4275n/a def test_implicit_context(self):
4276n/a Decimal = self.decimal.Decimal
4277n/a localcontext = self.decimal.localcontext
4278n/a
4279n/a with localcontext() as c:
4280n/a c.prec = 1
4281n/a c.Emax = 1
4282n/a c.Emin = -1
4283n/a
4284n/a # abs
4285n/a self.assertEqual(abs(Decimal("-10")), 10)
4286n/a # add
4287n/a self.assertEqual(Decimal("7") + 1, 8)
4288n/a # divide
4289n/a self.assertEqual(Decimal("10") / 5, 2)
4290n/a # divide_int
4291n/a self.assertEqual(Decimal("10") // 7, 1)
4292n/a # fma
4293n/a self.assertEqual(Decimal("1.2").fma(Decimal("0.01"), 1), 1)
4294n/a self.assertIs(Decimal("NaN").fma(7, 1).is_nan(), True)
4295n/a # three arg power
4296n/a self.assertEqual(pow(Decimal(10), 2, 7), 2)
4297n/a # exp
4298n/a self.assertEqual(Decimal("1.01").exp(), 3)
4299n/a # is_normal
4300n/a self.assertIs(Decimal("0.01").is_normal(), False)
4301n/a # is_subnormal
4302n/a self.assertIs(Decimal("0.01").is_subnormal(), True)
4303n/a # ln
4304n/a self.assertEqual(Decimal("20").ln(), 3)
4305n/a # log10
4306n/a self.assertEqual(Decimal("20").log10(), 1)
4307n/a # logb
4308n/a self.assertEqual(Decimal("580").logb(), 2)
4309n/a # logical_invert
4310n/a self.assertEqual(Decimal("10").logical_invert(), 1)
4311n/a # minus
4312n/a self.assertEqual(-Decimal("-10"), 10)
4313n/a # multiply
4314n/a self.assertEqual(Decimal("2") * 4, 8)
4315n/a # next_minus
4316n/a self.assertEqual(Decimal("10").next_minus(), 9)
4317n/a # next_plus
4318n/a self.assertEqual(Decimal("10").next_plus(), Decimal('2E+1'))
4319n/a # normalize
4320n/a self.assertEqual(Decimal("-10").normalize(), Decimal('-1E+1'))
4321n/a # number_class
4322n/a self.assertEqual(Decimal("10").number_class(), '+Normal')
4323n/a # plus
4324n/a self.assertEqual(+Decimal("-1"), -1)
4325n/a # remainder
4326n/a self.assertEqual(Decimal("10") % 7, 3)
4327n/a # subtract
4328n/a self.assertEqual(Decimal("10") - 7, 3)
4329n/a # to_integral_exact
4330n/a self.assertEqual(Decimal("1.12345").to_integral_exact(), 1)
4331n/a
4332n/a # Boolean functions
4333n/a self.assertTrue(Decimal("1").is_canonical())
4334n/a self.assertTrue(Decimal("1").is_finite())
4335n/a self.assertTrue(Decimal("1").is_finite())
4336n/a self.assertTrue(Decimal("snan").is_snan())
4337n/a self.assertTrue(Decimal("-1").is_signed())
4338n/a self.assertTrue(Decimal("0").is_zero())
4339n/a self.assertTrue(Decimal("0").is_zero())
4340n/a
4341n/a # Copy
4342n/a with localcontext() as c:
4343n/a c.prec = 10000
4344n/a x = 1228 ** 1523
4345n/a y = -Decimal(x)
4346n/a
4347n/a z = y.copy_abs()
4348n/a self.assertEqual(z, x)
4349n/a
4350n/a z = y.copy_negate()
4351n/a self.assertEqual(z, x)
4352n/a
4353n/a z = y.copy_sign(Decimal(1))
4354n/a self.assertEqual(z, x)
4355n/a
4356n/a def test_divmod(self):
4357n/a Decimal = self.decimal.Decimal
4358n/a localcontext = self.decimal.localcontext
4359n/a InvalidOperation = self.decimal.InvalidOperation
4360n/a DivisionByZero = self.decimal.DivisionByZero
4361n/a
4362n/a with localcontext() as c:
4363n/a q, r = divmod(Decimal("10912837129"), 1001)
4364n/a self.assertEqual(q, Decimal('10901935'))
4365n/a self.assertEqual(r, Decimal('194'))
4366n/a
4367n/a q, r = divmod(Decimal("NaN"), 7)
4368n/a self.assertTrue(q.is_nan() and r.is_nan())
4369n/a
4370n/a c.traps[InvalidOperation] = False
4371n/a q, r = divmod(Decimal("NaN"), 7)
4372n/a self.assertTrue(q.is_nan() and r.is_nan())
4373n/a
4374n/a c.traps[InvalidOperation] = False
4375n/a c.clear_flags()
4376n/a q, r = divmod(Decimal("inf"), Decimal("inf"))
4377n/a self.assertTrue(q.is_nan() and r.is_nan())
4378n/a self.assertTrue(c.flags[InvalidOperation])
4379n/a
4380n/a c.clear_flags()
4381n/a q, r = divmod(Decimal("inf"), 101)
4382n/a self.assertTrue(q.is_infinite() and r.is_nan())
4383n/a self.assertTrue(c.flags[InvalidOperation])
4384n/a
4385n/a c.clear_flags()
4386n/a q, r = divmod(Decimal(0), 0)
4387n/a self.assertTrue(q.is_nan() and r.is_nan())
4388n/a self.assertTrue(c.flags[InvalidOperation])
4389n/a
4390n/a c.traps[DivisionByZero] = False
4391n/a c.clear_flags()
4392n/a q, r = divmod(Decimal(11), 0)
4393n/a self.assertTrue(q.is_infinite() and r.is_nan())
4394n/a self.assertTrue(c.flags[InvalidOperation] and
4395n/a c.flags[DivisionByZero])
4396n/a
4397n/a def test_power(self):
4398n/a Decimal = self.decimal.Decimal
4399n/a localcontext = self.decimal.localcontext
4400n/a Overflow = self.decimal.Overflow
4401n/a Rounded = self.decimal.Rounded
4402n/a
4403n/a with localcontext() as c:
4404n/a c.prec = 3
4405n/a c.clear_flags()
4406n/a self.assertEqual(Decimal("1.0") ** 100, Decimal('1.00'))
4407n/a self.assertTrue(c.flags[Rounded])
4408n/a
4409n/a c.prec = 1
4410n/a c.Emax = 1
4411n/a c.Emin = -1
4412n/a c.clear_flags()
4413n/a c.traps[Overflow] = False
4414n/a self.assertEqual(Decimal(10000) ** Decimal("0.5"), Decimal('inf'))
4415n/a self.assertTrue(c.flags[Overflow])
4416n/a
4417n/a def test_quantize(self):
4418n/a Decimal = self.decimal.Decimal
4419n/a localcontext = self.decimal.localcontext
4420n/a InvalidOperation = self.decimal.InvalidOperation
4421n/a
4422n/a with localcontext() as c:
4423n/a c.prec = 1
4424n/a c.Emax = 1
4425n/a c.Emin = -1
4426n/a c.traps[InvalidOperation] = False
4427n/a x = Decimal(99).quantize(Decimal("1e1"))
4428n/a self.assertTrue(x.is_nan())
4429n/a
4430n/a def test_radix(self):
4431n/a Decimal = self.decimal.Decimal
4432n/a getcontext = self.decimal.getcontext
4433n/a
4434n/a c = getcontext()
4435n/a self.assertEqual(Decimal("1").radix(), 10)
4436n/a self.assertEqual(c.radix(), 10)
4437n/a
4438n/a def test_rop(self):
4439n/a Decimal = self.decimal.Decimal
4440n/a
4441n/a for attr in ('__radd__', '__rsub__', '__rmul__', '__rtruediv__',
4442n/a '__rdivmod__', '__rmod__', '__rfloordiv__', '__rpow__'):
4443n/a self.assertIs(getattr(Decimal("1"), attr)("xyz"), NotImplemented)
4444n/a
4445n/a def test_round(self):
4446n/a # Python3 behavior: round() returns Decimal
4447n/a Decimal = self.decimal.Decimal
4448n/a getcontext = self.decimal.getcontext
4449n/a
4450n/a c = getcontext()
4451n/a c.prec = 28
4452n/a
4453n/a self.assertEqual(str(Decimal("9.99").__round__()), "10")
4454n/a self.assertEqual(str(Decimal("9.99e-5").__round__()), "0")
4455n/a self.assertEqual(str(Decimal("1.23456789").__round__(5)), "1.23457")
4456n/a self.assertEqual(str(Decimal("1.2345").__round__(10)), "1.2345000000")
4457n/a self.assertEqual(str(Decimal("1.2345").__round__(-10)), "0E+10")
4458n/a
4459n/a self.assertRaises(TypeError, Decimal("1.23").__round__, "5")
4460n/a self.assertRaises(TypeError, Decimal("1.23").__round__, 5, 8)
4461n/a
4462n/a def test_create_decimal(self):
4463n/a c = self.decimal.Context()
4464n/a self.assertRaises(ValueError, c.create_decimal, ["%"])
4465n/a
4466n/a def test_int(self):
4467n/a Decimal = self.decimal.Decimal
4468n/a localcontext = self.decimal.localcontext
4469n/a
4470n/a with localcontext() as c:
4471n/a c.prec = 9999
4472n/a x = Decimal(1221**1271) / 10**3923
4473n/a self.assertEqual(int(x), 1)
4474n/a self.assertEqual(x.to_integral(), 2)
4475n/a
4476n/a def test_copy(self):
4477n/a Context = self.decimal.Context
4478n/a
4479n/a c = Context()
4480n/a c.prec = 10000
4481n/a x = -(1172 ** 1712)
4482n/a
4483n/a y = c.copy_abs(x)
4484n/a self.assertEqual(y, -x)
4485n/a
4486n/a y = c.copy_negate(x)
4487n/a self.assertEqual(y, -x)
4488n/a
4489n/a y = c.copy_sign(x, 1)
4490n/a self.assertEqual(y, -x)
4491n/a
4492n/aclass CCoverage(Coverage):
4493n/a decimal = C
4494n/aclass PyCoverage(Coverage):
4495n/a decimal = P
4496n/a
4497n/aclass PyFunctionality(unittest.TestCase):
4498n/a """Extra functionality in decimal.py"""
4499n/a
4500n/a def test_py_alternate_formatting(self):
4501n/a # triples giving a format, a Decimal, and the expected result
4502n/a Decimal = P.Decimal
4503n/a localcontext = P.localcontext
4504n/a
4505n/a test_values = [
4506n/a # Issue 7094: Alternate formatting (specified by #)
4507n/a ('.0e', '1.0', '1e+0'),
4508n/a ('#.0e', '1.0', '1.e+0'),
4509n/a ('.0f', '1.0', '1'),
4510n/a ('#.0f', '1.0', '1.'),
4511n/a ('g', '1.1', '1.1'),
4512n/a ('#g', '1.1', '1.1'),
4513n/a ('.0g', '1', '1'),
4514n/a ('#.0g', '1', '1.'),
4515n/a ('.0%', '1.0', '100%'),
4516n/a ('#.0%', '1.0', '100.%'),
4517n/a ]
4518n/a for fmt, d, result in test_values:
4519n/a self.assertEqual(format(Decimal(d), fmt), result)
4520n/a
4521n/aclass PyWhitebox(unittest.TestCase):
4522n/a """White box testing for decimal.py"""
4523n/a
4524n/a def test_py_exact_power(self):
4525n/a # Rarely exercised lines in _power_exact.
4526n/a Decimal = P.Decimal
4527n/a localcontext = P.localcontext
4528n/a
4529n/a with localcontext() as c:
4530n/a c.prec = 8
4531n/a x = Decimal(2**16) ** Decimal("-0.5")
4532n/a self.assertEqual(x, Decimal('0.00390625'))
4533n/a
4534n/a x = Decimal(2**16) ** Decimal("-0.6")
4535n/a self.assertEqual(x, Decimal('0.0012885819'))
4536n/a
4537n/a x = Decimal("256e7") ** Decimal("-0.5")
4538n/a
4539n/a x = Decimal(152587890625) ** Decimal('-0.0625')
4540n/a self.assertEqual(x, Decimal("0.2"))
4541n/a
4542n/a x = Decimal("152587890625e7") ** Decimal('-0.0625')
4543n/a
4544n/a x = Decimal(5**2659) ** Decimal('-0.0625')
4545n/a
4546n/a c.prec = 1
4547n/a x = Decimal("152587890625") ** Decimal('-0.5')
4548n/a c.prec = 201
4549n/a x = Decimal(2**578) ** Decimal("-0.5")
4550n/a
4551n/a def test_py_immutability_operations(self):
4552n/a # Do operations and check that it didn't change internal objects.
4553n/a Decimal = P.Decimal
4554n/a DefaultContext = P.DefaultContext
4555n/a setcontext = P.setcontext
4556n/a
4557n/a c = DefaultContext.copy()
4558n/a c.traps = dict((s, 0) for s in OrderedSignals[P])
4559n/a setcontext(c)
4560n/a
4561n/a d1 = Decimal('-25e55')
4562n/a b1 = Decimal('-25e55')
4563n/a d2 = Decimal('33e+33')
4564n/a b2 = Decimal('33e+33')
4565n/a
4566n/a def checkSameDec(operation, useOther=False):
4567n/a if useOther:
4568n/a eval("d1." + operation + "(d2)")
4569n/a self.assertEqual(d1._sign, b1._sign)
4570n/a self.assertEqual(d1._int, b1._int)
4571n/a self.assertEqual(d1._exp, b1._exp)
4572n/a self.assertEqual(d2._sign, b2._sign)
4573n/a self.assertEqual(d2._int, b2._int)
4574n/a self.assertEqual(d2._exp, b2._exp)
4575n/a else:
4576n/a eval("d1." + operation + "()")
4577n/a self.assertEqual(d1._sign, b1._sign)
4578n/a self.assertEqual(d1._int, b1._int)
4579n/a self.assertEqual(d1._exp, b1._exp)
4580n/a
4581n/a Decimal(d1)
4582n/a self.assertEqual(d1._sign, b1._sign)
4583n/a self.assertEqual(d1._int, b1._int)
4584n/a self.assertEqual(d1._exp, b1._exp)
4585n/a
4586n/a checkSameDec("__abs__")
4587n/a checkSameDec("__add__", True)
4588n/a checkSameDec("__divmod__", True)
4589n/a checkSameDec("__eq__", True)
4590n/a checkSameDec("__ne__", True)
4591n/a checkSameDec("__le__", True)
4592n/a checkSameDec("__lt__", True)
4593n/a checkSameDec("__ge__", True)
4594n/a checkSameDec("__gt__", True)
4595n/a checkSameDec("__float__")
4596n/a checkSameDec("__floordiv__", True)
4597n/a checkSameDec("__hash__")
4598n/a checkSameDec("__int__")
4599n/a checkSameDec("__trunc__")
4600n/a checkSameDec("__mod__", True)
4601n/a checkSameDec("__mul__", True)
4602n/a checkSameDec("__neg__")
4603n/a checkSameDec("__bool__")
4604n/a checkSameDec("__pos__")
4605n/a checkSameDec("__pow__", True)
4606n/a checkSameDec("__radd__", True)
4607n/a checkSameDec("__rdivmod__", True)
4608n/a checkSameDec("__repr__")
4609n/a checkSameDec("__rfloordiv__", True)
4610n/a checkSameDec("__rmod__", True)
4611n/a checkSameDec("__rmul__", True)
4612n/a checkSameDec("__rpow__", True)
4613n/a checkSameDec("__rsub__", True)
4614n/a checkSameDec("__str__")
4615n/a checkSameDec("__sub__", True)
4616n/a checkSameDec("__truediv__", True)
4617n/a checkSameDec("adjusted")
4618n/a checkSameDec("as_tuple")
4619n/a checkSameDec("compare", True)
4620n/a checkSameDec("max", True)
4621n/a checkSameDec("min", True)
4622n/a checkSameDec("normalize")
4623n/a checkSameDec("quantize", True)
4624n/a checkSameDec("remainder_near", True)
4625n/a checkSameDec("same_quantum", True)
4626n/a checkSameDec("sqrt")
4627n/a checkSameDec("to_eng_string")
4628n/a checkSameDec("to_integral")
4629n/a
4630n/a def test_py_decimal_id(self):
4631n/a Decimal = P.Decimal
4632n/a
4633n/a d = Decimal(45)
4634n/a e = Decimal(d)
4635n/a self.assertEqual(str(e), '45')
4636n/a self.assertNotEqual(id(d), id(e))
4637n/a
4638n/a def test_py_rescale(self):
4639n/a # Coverage
4640n/a Decimal = P.Decimal
4641n/a localcontext = P.localcontext
4642n/a
4643n/a with localcontext() as c:
4644n/a x = Decimal("NaN")._rescale(3, ROUND_UP)
4645n/a self.assertTrue(x.is_nan())
4646n/a
4647n/a def test_py__round(self):
4648n/a # Coverage
4649n/a Decimal = P.Decimal
4650n/a
4651n/a self.assertRaises(ValueError, Decimal("3.1234")._round, 0, ROUND_UP)
4652n/a
4653n/aclass CFunctionality(unittest.TestCase):
4654n/a """Extra functionality in _decimal"""
4655n/a
4656n/a @requires_extra_functionality
4657n/a def test_c_ieee_context(self):
4658n/a # issue 8786: Add support for IEEE 754 contexts to decimal module.
4659n/a IEEEContext = C.IEEEContext
4660n/a DECIMAL32 = C.DECIMAL32
4661n/a DECIMAL64 = C.DECIMAL64
4662n/a DECIMAL128 = C.DECIMAL128
4663n/a
4664n/a def assert_rest(self, context):
4665n/a self.assertEqual(context.clamp, 1)
4666n/a assert_signals(self, context, 'traps', [])
4667n/a assert_signals(self, context, 'flags', [])
4668n/a
4669n/a c = IEEEContext(DECIMAL32)
4670n/a self.assertEqual(c.prec, 7)
4671n/a self.assertEqual(c.Emax, 96)
4672n/a self.assertEqual(c.Emin, -95)
4673n/a assert_rest(self, c)
4674n/a
4675n/a c = IEEEContext(DECIMAL64)
4676n/a self.assertEqual(c.prec, 16)
4677n/a self.assertEqual(c.Emax, 384)
4678n/a self.assertEqual(c.Emin, -383)
4679n/a assert_rest(self, c)
4680n/a
4681n/a c = IEEEContext(DECIMAL128)
4682n/a self.assertEqual(c.prec, 34)
4683n/a self.assertEqual(c.Emax, 6144)
4684n/a self.assertEqual(c.Emin, -6143)
4685n/a assert_rest(self, c)
4686n/a
4687n/a # Invalid values
4688n/a self.assertRaises(OverflowError, IEEEContext, 2**63)
4689n/a self.assertRaises(ValueError, IEEEContext, -1)
4690n/a self.assertRaises(ValueError, IEEEContext, 1024)
4691n/a
4692n/a @requires_extra_functionality
4693n/a def test_c_context(self):
4694n/a Context = C.Context
4695n/a
4696n/a c = Context(flags=C.DecClamped, traps=C.DecRounded)
4697n/a self.assertEqual(c._flags, C.DecClamped)
4698n/a self.assertEqual(c._traps, C.DecRounded)
4699n/a
4700n/a @requires_extra_functionality
4701n/a def test_constants(self):
4702n/a # Condition flags
4703n/a cond = (
4704n/a C.DecClamped, C.DecConversionSyntax, C.DecDivisionByZero,
4705n/a C.DecDivisionImpossible, C.DecDivisionUndefined,
4706n/a C.DecFpuError, C.DecInexact, C.DecInvalidContext,
4707n/a C.DecInvalidOperation, C.DecMallocError,
4708n/a C.DecFloatOperation, C.DecOverflow, C.DecRounded,
4709n/a C.DecSubnormal, C.DecUnderflow
4710n/a )
4711n/a
4712n/a # IEEEContext
4713n/a self.assertEqual(C.DECIMAL32, 32)
4714n/a self.assertEqual(C.DECIMAL64, 64)
4715n/a self.assertEqual(C.DECIMAL128, 128)
4716n/a self.assertEqual(C.IEEE_CONTEXT_MAX_BITS, 512)
4717n/a
4718n/a # Conditions
4719n/a for i, v in enumerate(cond):
4720n/a self.assertEqual(v, 1<<i)
4721n/a
4722n/a self.assertEqual(C.DecIEEEInvalidOperation,
4723n/a C.DecConversionSyntax|
4724n/a C.DecDivisionImpossible|
4725n/a C.DecDivisionUndefined|
4726n/a C.DecFpuError|
4727n/a C.DecInvalidContext|
4728n/a C.DecInvalidOperation|
4729n/a C.DecMallocError)
4730n/a
4731n/a self.assertEqual(C.DecErrors,
4732n/a C.DecIEEEInvalidOperation|
4733n/a C.DecDivisionByZero)
4734n/a
4735n/a self.assertEqual(C.DecTraps,
4736n/a C.DecErrors|C.DecOverflow|C.DecUnderflow)
4737n/a
4738n/aclass CWhitebox(unittest.TestCase):
4739n/a """Whitebox testing for _decimal"""
4740n/a
4741n/a def test_bignum(self):
4742n/a # Not exactly whitebox, but too slow with pydecimal.
4743n/a
4744n/a Decimal = C.Decimal
4745n/a localcontext = C.localcontext
4746n/a
4747n/a b1 = 10**35
4748n/a b2 = 10**36
4749n/a with localcontext() as c:
4750n/a c.prec = 1000000
4751n/a for i in range(5):
4752n/a a = random.randrange(b1, b2)
4753n/a b = random.randrange(1000, 1200)
4754n/a x = a ** b
4755n/a y = Decimal(a) ** Decimal(b)
4756n/a self.assertEqual(x, y)
4757n/a
4758n/a def test_invalid_construction(self):
4759n/a self.assertRaises(TypeError, C.Decimal, 9, "xyz")
4760n/a
4761n/a def test_c_input_restriction(self):
4762n/a # Too large for _decimal to be converted exactly
4763n/a Decimal = C.Decimal
4764n/a InvalidOperation = C.InvalidOperation
4765n/a Context = C.Context
4766n/a localcontext = C.localcontext
4767n/a
4768n/a with localcontext(Context()):
4769n/a self.assertRaises(InvalidOperation, Decimal,
4770n/a "1e9999999999999999999")
4771n/a
4772n/a def test_c_context_repr(self):
4773n/a # This test is _decimal-only because flags are not printed
4774n/a # in the same order.
4775n/a DefaultContext = C.DefaultContext
4776n/a FloatOperation = C.FloatOperation
4777n/a
4778n/a c = DefaultContext.copy()
4779n/a
4780n/a c.prec = 425000000
4781n/a c.Emax = 425000000
4782n/a c.Emin = -425000000
4783n/a c.rounding = ROUND_HALF_DOWN
4784n/a c.capitals = 0
4785n/a c.clamp = 1
4786n/a for sig in OrderedSignals[C]:
4787n/a c.flags[sig] = True
4788n/a c.traps[sig] = True
4789n/a c.flags[FloatOperation] = True
4790n/a c.traps[FloatOperation] = True
4791n/a
4792n/a s = c.__repr__()
4793n/a t = "Context(prec=425000000, rounding=ROUND_HALF_DOWN, " \
4794n/a "Emin=-425000000, Emax=425000000, capitals=0, clamp=1, " \
4795n/a "flags=[Clamped, InvalidOperation, DivisionByZero, Inexact, " \
4796n/a "FloatOperation, Overflow, Rounded, Subnormal, Underflow], " \
4797n/a "traps=[Clamped, InvalidOperation, DivisionByZero, Inexact, " \
4798n/a "FloatOperation, Overflow, Rounded, Subnormal, Underflow])"
4799n/a self.assertEqual(s, t)
4800n/a
4801n/a def test_c_context_errors(self):
4802n/a Context = C.Context
4803n/a InvalidOperation = C.InvalidOperation
4804n/a Overflow = C.Overflow
4805n/a FloatOperation = C.FloatOperation
4806n/a localcontext = C.localcontext
4807n/a getcontext = C.getcontext
4808n/a setcontext = C.setcontext
4809n/a HAVE_CONFIG_64 = (C.MAX_PREC > 425000000)
4810n/a
4811n/a c = Context()
4812n/a
4813n/a # SignalDict: input validation
4814n/a self.assertRaises(KeyError, c.flags.__setitem__, 801, 0)
4815n/a self.assertRaises(KeyError, c.traps.__setitem__, 801, 0)
4816n/a self.assertRaises(ValueError, c.flags.__delitem__, Overflow)
4817n/a self.assertRaises(ValueError, c.traps.__delitem__, InvalidOperation)
4818n/a self.assertRaises(TypeError, setattr, c, 'flags', ['x'])
4819n/a self.assertRaises(TypeError, setattr, c,'traps', ['y'])
4820n/a self.assertRaises(KeyError, setattr, c, 'flags', {0:1})
4821n/a self.assertRaises(KeyError, setattr, c, 'traps', {0:1})
4822n/a
4823n/a # Test assignment from a signal dict with the correct length but
4824n/a # one invalid key.
4825n/a d = c.flags.copy()
4826n/a del d[FloatOperation]
4827n/a d["XYZ"] = 91283719
4828n/a self.assertRaises(KeyError, setattr, c, 'flags', d)
4829n/a self.assertRaises(KeyError, setattr, c, 'traps', d)
4830n/a
4831n/a # Input corner cases
4832n/a int_max = 2**63-1 if HAVE_CONFIG_64 else 2**31-1
4833n/a gt_max_emax = 10**18 if HAVE_CONFIG_64 else 10**9
4834n/a
4835n/a # prec, Emax, Emin
4836n/a for attr in ['prec', 'Emax']:
4837n/a self.assertRaises(ValueError, setattr, c, attr, gt_max_emax)
4838n/a self.assertRaises(ValueError, setattr, c, 'Emin', -gt_max_emax)
4839n/a
4840n/a # prec, Emax, Emin in context constructor
4841n/a self.assertRaises(ValueError, Context, prec=gt_max_emax)
4842n/a self.assertRaises(ValueError, Context, Emax=gt_max_emax)
4843n/a self.assertRaises(ValueError, Context, Emin=-gt_max_emax)
4844n/a
4845n/a # Overflow in conversion
4846n/a self.assertRaises(OverflowError, Context, prec=int_max+1)
4847n/a self.assertRaises(OverflowError, Context, Emax=int_max+1)
4848n/a self.assertRaises(OverflowError, Context, Emin=-int_max-2)
4849n/a self.assertRaises(OverflowError, Context, clamp=int_max+1)
4850n/a self.assertRaises(OverflowError, Context, capitals=int_max+1)
4851n/a
4852n/a # OverflowError, general ValueError
4853n/a for attr in ('prec', 'Emin', 'Emax', 'capitals', 'clamp'):
4854n/a self.assertRaises(OverflowError, setattr, c, attr, int_max+1)
4855n/a self.assertRaises(OverflowError, setattr, c, attr, -int_max-2)
4856n/a if sys.platform != 'win32':
4857n/a self.assertRaises(ValueError, setattr, c, attr, int_max)
4858n/a self.assertRaises(ValueError, setattr, c, attr, -int_max-1)
4859n/a
4860n/a # OverflowError: _unsafe_setprec, _unsafe_setemin, _unsafe_setemax
4861n/a if C.MAX_PREC == 425000000:
4862n/a self.assertRaises(OverflowError, getattr(c, '_unsafe_setprec'),
4863n/a int_max+1)
4864n/a self.assertRaises(OverflowError, getattr(c, '_unsafe_setemax'),
4865n/a int_max+1)
4866n/a self.assertRaises(OverflowError, getattr(c, '_unsafe_setemin'),
4867n/a -int_max-2)
4868n/a
4869n/a # ValueError: _unsafe_setprec, _unsafe_setemin, _unsafe_setemax
4870n/a if C.MAX_PREC == 425000000:
4871n/a self.assertRaises(ValueError, getattr(c, '_unsafe_setprec'), 0)
4872n/a self.assertRaises(ValueError, getattr(c, '_unsafe_setprec'),
4873n/a 1070000001)
4874n/a self.assertRaises(ValueError, getattr(c, '_unsafe_setemax'), -1)
4875n/a self.assertRaises(ValueError, getattr(c, '_unsafe_setemax'),
4876n/a 1070000001)
4877n/a self.assertRaises(ValueError, getattr(c, '_unsafe_setemin'),
4878n/a -1070000001)
4879n/a self.assertRaises(ValueError, getattr(c, '_unsafe_setemin'), 1)
4880n/a
4881n/a # capitals, clamp
4882n/a for attr in ['capitals', 'clamp']:
4883n/a self.assertRaises(ValueError, setattr, c, attr, -1)
4884n/a self.assertRaises(ValueError, setattr, c, attr, 2)
4885n/a self.assertRaises(TypeError, setattr, c, attr, [1,2,3])
4886n/a if HAVE_CONFIG_64:
4887n/a self.assertRaises(ValueError, setattr, c, attr, 2**32)
4888n/a self.assertRaises(ValueError, setattr, c, attr, 2**32+1)
4889n/a
4890n/a # Invalid local context
4891n/a self.assertRaises(TypeError, exec, 'with localcontext("xyz"): pass',
4892n/a locals())
4893n/a self.assertRaises(TypeError, exec,
4894n/a 'with localcontext(context=getcontext()): pass',
4895n/a locals())
4896n/a
4897n/a # setcontext
4898n/a saved_context = getcontext()
4899n/a self.assertRaises(TypeError, setcontext, "xyz")
4900n/a setcontext(saved_context)
4901n/a
4902n/a def test_rounding_strings_interned(self):
4903n/a
4904n/a self.assertIs(C.ROUND_UP, P.ROUND_UP)
4905n/a self.assertIs(C.ROUND_DOWN, P.ROUND_DOWN)
4906n/a self.assertIs(C.ROUND_CEILING, P.ROUND_CEILING)
4907n/a self.assertIs(C.ROUND_FLOOR, P.ROUND_FLOOR)
4908n/a self.assertIs(C.ROUND_HALF_UP, P.ROUND_HALF_UP)
4909n/a self.assertIs(C.ROUND_HALF_DOWN, P.ROUND_HALF_DOWN)
4910n/a self.assertIs(C.ROUND_HALF_EVEN, P.ROUND_HALF_EVEN)
4911n/a self.assertIs(C.ROUND_05UP, P.ROUND_05UP)
4912n/a
4913n/a @requires_extra_functionality
4914n/a def test_c_context_errors_extra(self):
4915n/a Context = C.Context
4916n/a InvalidOperation = C.InvalidOperation
4917n/a Overflow = C.Overflow
4918n/a localcontext = C.localcontext
4919n/a getcontext = C.getcontext
4920n/a setcontext = C.setcontext
4921n/a HAVE_CONFIG_64 = (C.MAX_PREC > 425000000)
4922n/a
4923n/a c = Context()
4924n/a
4925n/a # Input corner cases
4926n/a int_max = 2**63-1 if HAVE_CONFIG_64 else 2**31-1
4927n/a
4928n/a # OverflowError, general ValueError
4929n/a self.assertRaises(OverflowError, setattr, c, '_allcr', int_max+1)
4930n/a self.assertRaises(OverflowError, setattr, c, '_allcr', -int_max-2)
4931n/a if sys.platform != 'win32':
4932n/a self.assertRaises(ValueError, setattr, c, '_allcr', int_max)
4933n/a self.assertRaises(ValueError, setattr, c, '_allcr', -int_max-1)
4934n/a
4935n/a # OverflowError, general TypeError
4936n/a for attr in ('_flags', '_traps'):
4937n/a self.assertRaises(OverflowError, setattr, c, attr, int_max+1)
4938n/a self.assertRaises(OverflowError, setattr, c, attr, -int_max-2)
4939n/a if sys.platform != 'win32':
4940n/a self.assertRaises(TypeError, setattr, c, attr, int_max)
4941n/a self.assertRaises(TypeError, setattr, c, attr, -int_max-1)
4942n/a
4943n/a # _allcr
4944n/a self.assertRaises(ValueError, setattr, c, '_allcr', -1)
4945n/a self.assertRaises(ValueError, setattr, c, '_allcr', 2)
4946n/a self.assertRaises(TypeError, setattr, c, '_allcr', [1,2,3])
4947n/a if HAVE_CONFIG_64:
4948n/a self.assertRaises(ValueError, setattr, c, '_allcr', 2**32)
4949n/a self.assertRaises(ValueError, setattr, c, '_allcr', 2**32+1)
4950n/a
4951n/a # _flags, _traps
4952n/a for attr in ['_flags', '_traps']:
4953n/a self.assertRaises(TypeError, setattr, c, attr, 999999)
4954n/a self.assertRaises(TypeError, setattr, c, attr, 'x')
4955n/a
4956n/a def test_c_valid_context(self):
4957n/a # These tests are for code coverage in _decimal.
4958n/a DefaultContext = C.DefaultContext
4959n/a Clamped = C.Clamped
4960n/a Underflow = C.Underflow
4961n/a Inexact = C.Inexact
4962n/a Rounded = C.Rounded
4963n/a Subnormal = C.Subnormal
4964n/a
4965n/a c = DefaultContext.copy()
4966n/a
4967n/a # Exercise all getters and setters
4968n/a c.prec = 34
4969n/a c.rounding = ROUND_HALF_UP
4970n/a c.Emax = 3000
4971n/a c.Emin = -3000
4972n/a c.capitals = 1
4973n/a c.clamp = 0
4974n/a
4975n/a self.assertEqual(c.prec, 34)
4976n/a self.assertEqual(c.rounding, ROUND_HALF_UP)
4977n/a self.assertEqual(c.Emin, -3000)
4978n/a self.assertEqual(c.Emax, 3000)
4979n/a self.assertEqual(c.capitals, 1)
4980n/a self.assertEqual(c.clamp, 0)
4981n/a
4982n/a self.assertEqual(c.Etiny(), -3033)
4983n/a self.assertEqual(c.Etop(), 2967)
4984n/a
4985n/a # Exercise all unsafe setters
4986n/a if C.MAX_PREC == 425000000:
4987n/a c._unsafe_setprec(999999999)
4988n/a c._unsafe_setemax(999999999)
4989n/a c._unsafe_setemin(-999999999)
4990n/a self.assertEqual(c.prec, 999999999)
4991n/a self.assertEqual(c.Emax, 999999999)
4992n/a self.assertEqual(c.Emin, -999999999)
4993n/a
4994n/a @requires_extra_functionality
4995n/a def test_c_valid_context_extra(self):
4996n/a DefaultContext = C.DefaultContext
4997n/a
4998n/a c = DefaultContext.copy()
4999n/a self.assertEqual(c._allcr, 1)
5000n/a c._allcr = 0
5001n/a self.assertEqual(c._allcr, 0)
5002n/a
5003n/a def test_c_round(self):
5004n/a # Restricted input.
5005n/a Decimal = C.Decimal
5006n/a InvalidOperation = C.InvalidOperation
5007n/a localcontext = C.localcontext
5008n/a MAX_EMAX = C.MAX_EMAX
5009n/a MIN_ETINY = C.MIN_ETINY
5010n/a int_max = 2**63-1 if C.MAX_PREC > 425000000 else 2**31-1
5011n/a
5012n/a with localcontext() as c:
5013n/a c.traps[InvalidOperation] = True
5014n/a self.assertRaises(InvalidOperation, Decimal("1.23").__round__,
5015n/a -int_max-1)
5016n/a self.assertRaises(InvalidOperation, Decimal("1.23").__round__,
5017n/a int_max)
5018n/a self.assertRaises(InvalidOperation, Decimal("1").__round__,
5019n/a int(MAX_EMAX+1))
5020n/a self.assertRaises(C.InvalidOperation, Decimal("1").__round__,
5021n/a -int(MIN_ETINY-1))
5022n/a self.assertRaises(OverflowError, Decimal("1.23").__round__,
5023n/a -int_max-2)
5024n/a self.assertRaises(OverflowError, Decimal("1.23").__round__,
5025n/a int_max+1)
5026n/a
5027n/a def test_c_format(self):
5028n/a # Restricted input
5029n/a Decimal = C.Decimal
5030n/a HAVE_CONFIG_64 = (C.MAX_PREC > 425000000)
5031n/a
5032n/a self.assertRaises(TypeError, Decimal(1).__format__, "=10.10", [], 9)
5033n/a self.assertRaises(TypeError, Decimal(1).__format__, "=10.10", 9)
5034n/a self.assertRaises(TypeError, Decimal(1).__format__, [])
5035n/a
5036n/a self.assertRaises(ValueError, Decimal(1).__format__, "<>=10.10")
5037n/a maxsize = 2**63-1 if HAVE_CONFIG_64 else 2**31-1
5038n/a self.assertRaises(ValueError, Decimal("1.23456789").__format__,
5039n/a "=%d.1" % maxsize)
5040n/a
5041n/a def test_c_integral(self):
5042n/a Decimal = C.Decimal
5043n/a Inexact = C.Inexact
5044n/a localcontext = C.localcontext
5045n/a
5046n/a x = Decimal(10)
5047n/a self.assertEqual(x.to_integral(), 10)
5048n/a self.assertRaises(TypeError, x.to_integral, '10')
5049n/a self.assertRaises(TypeError, x.to_integral, 10, 'x')
5050n/a self.assertRaises(TypeError, x.to_integral, 10)
5051n/a
5052n/a self.assertEqual(x.to_integral_value(), 10)
5053n/a self.assertRaises(TypeError, x.to_integral_value, '10')
5054n/a self.assertRaises(TypeError, x.to_integral_value, 10, 'x')
5055n/a self.assertRaises(TypeError, x.to_integral_value, 10)
5056n/a
5057n/a self.assertEqual(x.to_integral_exact(), 10)
5058n/a self.assertRaises(TypeError, x.to_integral_exact, '10')
5059n/a self.assertRaises(TypeError, x.to_integral_exact, 10, 'x')
5060n/a self.assertRaises(TypeError, x.to_integral_exact, 10)
5061n/a
5062n/a with localcontext() as c:
5063n/a x = Decimal("99999999999999999999999999.9").to_integral_value(ROUND_UP)
5064n/a self.assertEqual(x, Decimal('100000000000000000000000000'))
5065n/a
5066n/a x = Decimal("99999999999999999999999999.9").to_integral_exact(ROUND_UP)
5067n/a self.assertEqual(x, Decimal('100000000000000000000000000'))
5068n/a
5069n/a c.traps[Inexact] = True
5070n/a self.assertRaises(Inexact, Decimal("999.9").to_integral_exact, ROUND_UP)
5071n/a
5072n/a def test_c_funcs(self):
5073n/a # Invalid arguments
5074n/a Decimal = C.Decimal
5075n/a InvalidOperation = C.InvalidOperation
5076n/a DivisionByZero = C.DivisionByZero
5077n/a getcontext = C.getcontext
5078n/a localcontext = C.localcontext
5079n/a
5080n/a self.assertEqual(Decimal('9.99e10').to_eng_string(), '99.9E+9')
5081n/a
5082n/a self.assertRaises(TypeError, pow, Decimal(1), 2, "3")
5083n/a self.assertRaises(TypeError, Decimal(9).number_class, "x", "y")
5084n/a self.assertRaises(TypeError, Decimal(9).same_quantum, 3, "x", "y")
5085n/a
5086n/a self.assertRaises(
5087n/a TypeError,
5088n/a Decimal("1.23456789").quantize, Decimal('1e-100000'), []
5089n/a )
5090n/a self.assertRaises(
5091n/a TypeError,
5092n/a Decimal("1.23456789").quantize, Decimal('1e-100000'), getcontext()
5093n/a )
5094n/a self.assertRaises(
5095n/a TypeError,
5096n/a Decimal("1.23456789").quantize, Decimal('1e-100000'), 10
5097n/a )
5098n/a self.assertRaises(
5099n/a TypeError,
5100n/a Decimal("1.23456789").quantize, Decimal('1e-100000'), ROUND_UP, 1000
5101n/a )
5102n/a
5103n/a with localcontext() as c:
5104n/a c.clear_traps()
5105n/a
5106n/a # Invalid arguments
5107n/a self.assertRaises(TypeError, c.copy_sign, Decimal(1), "x", "y")
5108n/a self.assertRaises(TypeError, c.canonical, 200)
5109n/a self.assertRaises(TypeError, c.is_canonical, 200)
5110n/a self.assertRaises(TypeError, c.divmod, 9, 8, "x", "y")
5111n/a self.assertRaises(TypeError, c.same_quantum, 9, 3, "x", "y")
5112n/a
5113n/a self.assertEqual(str(c.canonical(Decimal(200))), '200')
5114n/a self.assertEqual(c.radix(), 10)
5115n/a
5116n/a c.traps[DivisionByZero] = True
5117n/a self.assertRaises(DivisionByZero, Decimal(9).__divmod__, 0)
5118n/a self.assertRaises(DivisionByZero, c.divmod, 9, 0)
5119n/a self.assertTrue(c.flags[InvalidOperation])
5120n/a
5121n/a c.clear_flags()
5122n/a c.traps[InvalidOperation] = True
5123n/a self.assertRaises(InvalidOperation, Decimal(9).__divmod__, 0)
5124n/a self.assertRaises(InvalidOperation, c.divmod, 9, 0)
5125n/a self.assertTrue(c.flags[DivisionByZero])
5126n/a
5127n/a c.traps[InvalidOperation] = True
5128n/a c.prec = 2
5129n/a self.assertRaises(InvalidOperation, pow, Decimal(1000), 1, 501)
5130n/a
5131n/a def test_va_args_exceptions(self):
5132n/a Decimal = C.Decimal
5133n/a Context = C.Context
5134n/a
5135n/a x = Decimal("10001111111")
5136n/a
5137n/a for attr in ['exp', 'is_normal', 'is_subnormal', 'ln', 'log10',
5138n/a 'logb', 'logical_invert', 'next_minus', 'next_plus',
5139n/a 'normalize', 'number_class', 'sqrt', 'to_eng_string']:
5140n/a func = getattr(x, attr)
5141n/a self.assertRaises(TypeError, func, context="x")
5142n/a self.assertRaises(TypeError, func, "x", context=None)
5143n/a
5144n/a for attr in ['compare', 'compare_signal', 'logical_and',
5145n/a 'logical_or', 'max', 'max_mag', 'min', 'min_mag',
5146n/a 'remainder_near', 'rotate', 'scaleb', 'shift']:
5147n/a func = getattr(x, attr)
5148n/a self.assertRaises(TypeError, func, context="x")
5149n/a self.assertRaises(TypeError, func, "x", context=None)
5150n/a
5151n/a self.assertRaises(TypeError, x.to_integral, rounding=None, context=[])
5152n/a self.assertRaises(TypeError, x.to_integral, rounding={}, context=[])
5153n/a self.assertRaises(TypeError, x.to_integral, [], [])
5154n/a
5155n/a self.assertRaises(TypeError, x.to_integral_value, rounding=None, context=[])
5156n/a self.assertRaises(TypeError, x.to_integral_value, rounding={}, context=[])
5157n/a self.assertRaises(TypeError, x.to_integral_value, [], [])
5158n/a
5159n/a self.assertRaises(TypeError, x.to_integral_exact, rounding=None, context=[])
5160n/a self.assertRaises(TypeError, x.to_integral_exact, rounding={}, context=[])
5161n/a self.assertRaises(TypeError, x.to_integral_exact, [], [])
5162n/a
5163n/a self.assertRaises(TypeError, x.fma, 1, 2, context="x")
5164n/a self.assertRaises(TypeError, x.fma, 1, 2, "x", context=None)
5165n/a
5166n/a self.assertRaises(TypeError, x.quantize, 1, [], context=None)
5167n/a self.assertRaises(TypeError, x.quantize, 1, [], rounding=None)
5168n/a self.assertRaises(TypeError, x.quantize, 1, [], [])
5169n/a
5170n/a c = Context()
5171n/a self.assertRaises(TypeError, c.power, 1, 2, mod="x")
5172n/a self.assertRaises(TypeError, c.power, 1, "x", mod=None)
5173n/a self.assertRaises(TypeError, c.power, "x", 2, mod=None)
5174n/a
5175n/a @requires_extra_functionality
5176n/a def test_c_context_templates(self):
5177n/a self.assertEqual(
5178n/a C.BasicContext._traps,
5179n/a C.DecIEEEInvalidOperation|C.DecDivisionByZero|C.DecOverflow|
5180n/a C.DecUnderflow|C.DecClamped
5181n/a )
5182n/a self.assertEqual(
5183n/a C.DefaultContext._traps,
5184n/a C.DecIEEEInvalidOperation|C.DecDivisionByZero|C.DecOverflow
5185n/a )
5186n/a
5187n/a @requires_extra_functionality
5188n/a def test_c_signal_dict(self):
5189n/a
5190n/a # SignalDict coverage
5191n/a Context = C.Context
5192n/a DefaultContext = C.DefaultContext
5193n/a
5194n/a InvalidOperation = C.InvalidOperation
5195n/a DivisionByZero = C.DivisionByZero
5196n/a Overflow = C.Overflow
5197n/a Subnormal = C.Subnormal
5198n/a Underflow = C.Underflow
5199n/a Rounded = C.Rounded
5200n/a Inexact = C.Inexact
5201n/a Clamped = C.Clamped
5202n/a
5203n/a DecClamped = C.DecClamped
5204n/a DecInvalidOperation = C.DecInvalidOperation
5205n/a DecIEEEInvalidOperation = C.DecIEEEInvalidOperation
5206n/a
5207n/a def assertIsExclusivelySet(signal, signal_dict):
5208n/a for sig in signal_dict:
5209n/a if sig == signal:
5210n/a self.assertTrue(signal_dict[sig])
5211n/a else:
5212n/a self.assertFalse(signal_dict[sig])
5213n/a
5214n/a c = DefaultContext.copy()
5215n/a
5216n/a # Signal dict methods
5217n/a self.assertTrue(Overflow in c.traps)
5218n/a c.clear_traps()
5219n/a for k in c.traps.keys():
5220n/a c.traps[k] = True
5221n/a for v in c.traps.values():
5222n/a self.assertTrue(v)
5223n/a c.clear_traps()
5224n/a for k, v in c.traps.items():
5225n/a self.assertFalse(v)
5226n/a
5227n/a self.assertFalse(c.flags.get(Overflow))
5228n/a self.assertIs(c.flags.get("x"), None)
5229n/a self.assertEqual(c.flags.get("x", "y"), "y")
5230n/a self.assertRaises(TypeError, c.flags.get, "x", "y", "z")
5231n/a
5232n/a self.assertEqual(len(c.flags), len(c.traps))
5233n/a s = sys.getsizeof(c.flags)
5234n/a s = sys.getsizeof(c.traps)
5235n/a s = c.flags.__repr__()
5236n/a
5237n/a # Set flags/traps.
5238n/a c.clear_flags()
5239n/a c._flags = DecClamped
5240n/a self.assertTrue(c.flags[Clamped])
5241n/a
5242n/a c.clear_traps()
5243n/a c._traps = DecInvalidOperation
5244n/a self.assertTrue(c.traps[InvalidOperation])
5245n/a
5246n/a # Set flags/traps from dictionary.
5247n/a c.clear_flags()
5248n/a d = c.flags.copy()
5249n/a d[DivisionByZero] = True
5250n/a c.flags = d
5251n/a assertIsExclusivelySet(DivisionByZero, c.flags)
5252n/a
5253n/a c.clear_traps()
5254n/a d = c.traps.copy()
5255n/a d[Underflow] = True
5256n/a c.traps = d
5257n/a assertIsExclusivelySet(Underflow, c.traps)
5258n/a
5259n/a # Random constructors
5260n/a IntSignals = {
5261n/a Clamped: C.DecClamped,
5262n/a Rounded: C.DecRounded,
5263n/a Inexact: C.DecInexact,
5264n/a Subnormal: C.DecSubnormal,
5265n/a Underflow: C.DecUnderflow,
5266n/a Overflow: C.DecOverflow,
5267n/a DivisionByZero: C.DecDivisionByZero,
5268n/a InvalidOperation: C.DecIEEEInvalidOperation
5269n/a }
5270n/a IntCond = [
5271n/a C.DecDivisionImpossible, C.DecDivisionUndefined, C.DecFpuError,
5272n/a C.DecInvalidContext, C.DecInvalidOperation, C.DecMallocError,
5273n/a C.DecConversionSyntax,
5274n/a ]
5275n/a
5276n/a lim = len(OrderedSignals[C])
5277n/a for r in range(lim):
5278n/a for t in range(lim):
5279n/a for round in RoundingModes:
5280n/a flags = random.sample(OrderedSignals[C], r)
5281n/a traps = random.sample(OrderedSignals[C], t)
5282n/a prec = random.randrange(1, 10000)
5283n/a emin = random.randrange(-10000, 0)
5284n/a emax = random.randrange(0, 10000)
5285n/a clamp = random.randrange(0, 2)
5286n/a caps = random.randrange(0, 2)
5287n/a cr = random.randrange(0, 2)
5288n/a c = Context(prec=prec, rounding=round, Emin=emin, Emax=emax,
5289n/a capitals=caps, clamp=clamp, flags=list(flags),
5290n/a traps=list(traps))
5291n/a
5292n/a self.assertEqual(c.prec, prec)
5293n/a self.assertEqual(c.rounding, round)
5294n/a self.assertEqual(c.Emin, emin)
5295n/a self.assertEqual(c.Emax, emax)
5296n/a self.assertEqual(c.capitals, caps)
5297n/a self.assertEqual(c.clamp, clamp)
5298n/a
5299n/a f = 0
5300n/a for x in flags:
5301n/a f |= IntSignals[x]
5302n/a self.assertEqual(c._flags, f)
5303n/a
5304n/a f = 0
5305n/a for x in traps:
5306n/a f |= IntSignals[x]
5307n/a self.assertEqual(c._traps, f)
5308n/a
5309n/a for cond in IntCond:
5310n/a c._flags = cond
5311n/a self.assertTrue(c._flags&DecIEEEInvalidOperation)
5312n/a assertIsExclusivelySet(InvalidOperation, c.flags)
5313n/a
5314n/a for cond in IntCond:
5315n/a c._traps = cond
5316n/a self.assertTrue(c._traps&DecIEEEInvalidOperation)
5317n/a assertIsExclusivelySet(InvalidOperation, c.traps)
5318n/a
5319n/a def test_invalid_override(self):
5320n/a Decimal = C.Decimal
5321n/a
5322n/a try:
5323n/a from locale import CHAR_MAX
5324n/a except ImportError:
5325n/a self.skipTest('locale.CHAR_MAX not available')
5326n/a
5327n/a def make_grouping(lst):
5328n/a return ''.join([chr(x) for x in lst])
5329n/a
5330n/a def get_fmt(x, override=None, fmt='n'):
5331n/a return Decimal(x).__format__(fmt, override)
5332n/a
5333n/a invalid_grouping = {
5334n/a 'decimal_point' : ',',
5335n/a 'grouping' : make_grouping([255, 255, 0]),
5336n/a 'thousands_sep' : ','
5337n/a }
5338n/a invalid_dot = {
5339n/a 'decimal_point' : 'xxxxx',
5340n/a 'grouping' : make_grouping([3, 3, 0]),
5341n/a 'thousands_sep' : ','
5342n/a }
5343n/a invalid_sep = {
5344n/a 'decimal_point' : '.',
5345n/a 'grouping' : make_grouping([3, 3, 0]),
5346n/a 'thousands_sep' : 'yyyyy'
5347n/a }
5348n/a
5349n/a if CHAR_MAX == 127: # negative grouping in override
5350n/a self.assertRaises(ValueError, get_fmt, 12345,
5351n/a invalid_grouping, 'g')
5352n/a
5353n/a self.assertRaises(ValueError, get_fmt, 12345, invalid_dot, 'g')
5354n/a self.assertRaises(ValueError, get_fmt, 12345, invalid_sep, 'g')
5355n/a
5356n/a def test_exact_conversion(self):
5357n/a Decimal = C.Decimal
5358n/a localcontext = C.localcontext
5359n/a InvalidOperation = C.InvalidOperation
5360n/a
5361n/a with localcontext() as c:
5362n/a
5363n/a c.traps[InvalidOperation] = True
5364n/a
5365n/a # Clamped
5366n/a x = "0e%d" % sys.maxsize
5367n/a self.assertRaises(InvalidOperation, Decimal, x)
5368n/a
5369n/a x = "0e%d" % (-sys.maxsize-1)
5370n/a self.assertRaises(InvalidOperation, Decimal, x)
5371n/a
5372n/a # Overflow
5373n/a x = "1e%d" % sys.maxsize
5374n/a self.assertRaises(InvalidOperation, Decimal, x)
5375n/a
5376n/a # Underflow
5377n/a x = "1e%d" % (-sys.maxsize-1)
5378n/a self.assertRaises(InvalidOperation, Decimal, x)
5379n/a
5380n/a def test_from_tuple(self):
5381n/a Decimal = C.Decimal
5382n/a localcontext = C.localcontext
5383n/a InvalidOperation = C.InvalidOperation
5384n/a Overflow = C.Overflow
5385n/a Underflow = C.Underflow
5386n/a
5387n/a with localcontext() as c:
5388n/a
5389n/a c.traps[InvalidOperation] = True
5390n/a c.traps[Overflow] = True
5391n/a c.traps[Underflow] = True
5392n/a
5393n/a # SSIZE_MAX
5394n/a x = (1, (), sys.maxsize)
5395n/a self.assertEqual(str(c.create_decimal(x)), '-0E+999999')
5396n/a self.assertRaises(InvalidOperation, Decimal, x)
5397n/a
5398n/a x = (1, (0, 1, 2), sys.maxsize)
5399n/a self.assertRaises(Overflow, c.create_decimal, x)
5400n/a self.assertRaises(InvalidOperation, Decimal, x)
5401n/a
5402n/a # SSIZE_MIN
5403n/a x = (1, (), -sys.maxsize-1)
5404n/a self.assertEqual(str(c.create_decimal(x)), '-0E-1000026')
5405n/a self.assertRaises(InvalidOperation, Decimal, x)
5406n/a
5407n/a x = (1, (0, 1, 2), -sys.maxsize-1)
5408n/a self.assertRaises(Underflow, c.create_decimal, x)
5409n/a self.assertRaises(InvalidOperation, Decimal, x)
5410n/a
5411n/a # OverflowError
5412n/a x = (1, (), sys.maxsize+1)
5413n/a self.assertRaises(OverflowError, c.create_decimal, x)
5414n/a self.assertRaises(OverflowError, Decimal, x)
5415n/a
5416n/a x = (1, (), -sys.maxsize-2)
5417n/a self.assertRaises(OverflowError, c.create_decimal, x)
5418n/a self.assertRaises(OverflowError, Decimal, x)
5419n/a
5420n/a # Specials
5421n/a x = (1, (), "N")
5422n/a self.assertEqual(str(Decimal(x)), '-sNaN')
5423n/a x = (1, (0,), "N")
5424n/a self.assertEqual(str(Decimal(x)), '-sNaN')
5425n/a x = (1, (0, 1), "N")
5426n/a self.assertEqual(str(Decimal(x)), '-sNaN1')
5427n/a
5428n/a def test_sizeof(self):
5429n/a Decimal = C.Decimal
5430n/a HAVE_CONFIG_64 = (C.MAX_PREC > 425000000)
5431n/a
5432n/a self.assertGreater(Decimal(0).__sizeof__(), 0)
5433n/a if HAVE_CONFIG_64:
5434n/a x = Decimal(10**(19*24)).__sizeof__()
5435n/a y = Decimal(10**(19*25)).__sizeof__()
5436n/a self.assertEqual(y, x+8)
5437n/a else:
5438n/a x = Decimal(10**(9*24)).__sizeof__()
5439n/a y = Decimal(10**(9*25)).__sizeof__()
5440n/a self.assertEqual(y, x+4)
5441n/a
5442n/a def test_internal_use_of_overridden_methods(self):
5443n/a Decimal = C.Decimal
5444n/a
5445n/a # Unsound subtyping
5446n/a class X(float):
5447n/a def as_integer_ratio(self):
5448n/a return 1
5449n/a def __abs__(self):
5450n/a return self
5451n/a
5452n/a class Y(float):
5453n/a def __abs__(self):
5454n/a return [1]*200
5455n/a
5456n/a class I(int):
5457n/a def bit_length(self):
5458n/a return [1]*200
5459n/a
5460n/a class Z(float):
5461n/a def as_integer_ratio(self):
5462n/a return (I(1), I(1))
5463n/a def __abs__(self):
5464n/a return self
5465n/a
5466n/a for cls in X, Y, Z:
5467n/a self.assertEqual(Decimal.from_float(cls(101.1)),
5468n/a Decimal.from_float(101.1))
5469n/a
5470n/a@requires_docstrings
5471n/a@unittest.skipUnless(C, "test requires C version")
5472n/aclass SignatureTest(unittest.TestCase):
5473n/a """Function signatures"""
5474n/a
5475n/a def test_inspect_module(self):
5476n/a for attr in dir(P):
5477n/a if attr.startswith('_'):
5478n/a continue
5479n/a p_func = getattr(P, attr)
5480n/a c_func = getattr(C, attr)
5481n/a if (attr == 'Decimal' or attr == 'Context' or
5482n/a inspect.isfunction(p_func)):
5483n/a p_sig = inspect.signature(p_func)
5484n/a c_sig = inspect.signature(c_func)
5485n/a
5486n/a # parameter names:
5487n/a c_names = list(c_sig.parameters.keys())
5488n/a p_names = [x for x in p_sig.parameters.keys() if not
5489n/a x.startswith('_')]
5490n/a
5491n/a self.assertEqual(c_names, p_names,
5492n/a msg="parameter name mismatch in %s" % p_func)
5493n/a
5494n/a c_kind = [x.kind for x in c_sig.parameters.values()]
5495n/a p_kind = [x[1].kind for x in p_sig.parameters.items() if not
5496n/a x[0].startswith('_')]
5497n/a
5498n/a # parameters:
5499n/a if attr != 'setcontext':
5500n/a self.assertEqual(c_kind, p_kind,
5501n/a msg="parameter kind mismatch in %s" % p_func)
5502n/a
5503n/a def test_inspect_types(self):
5504n/a
5505n/a POS = inspect._ParameterKind.POSITIONAL_ONLY
5506n/a POS_KWD = inspect._ParameterKind.POSITIONAL_OR_KEYWORD
5507n/a
5508n/a # Type heuristic (type annotations would help!):
5509n/a pdict = {C: {'other': C.Decimal(1),
5510n/a 'third': C.Decimal(1),
5511n/a 'x': C.Decimal(1),
5512n/a 'y': C.Decimal(1),
5513n/a 'z': C.Decimal(1),
5514n/a 'a': C.Decimal(1),
5515n/a 'b': C.Decimal(1),
5516n/a 'c': C.Decimal(1),
5517n/a 'exp': C.Decimal(1),
5518n/a 'modulo': C.Decimal(1),
5519n/a 'num': "1",
5520n/a 'f': 1.0,
5521n/a 'rounding': C.ROUND_HALF_UP,
5522n/a 'context': C.getcontext()},
5523n/a P: {'other': P.Decimal(1),
5524n/a 'third': P.Decimal(1),
5525n/a 'a': P.Decimal(1),
5526n/a 'b': P.Decimal(1),
5527n/a 'c': P.Decimal(1),
5528n/a 'exp': P.Decimal(1),
5529n/a 'modulo': P.Decimal(1),
5530n/a 'num': "1",
5531n/a 'f': 1.0,
5532n/a 'rounding': P.ROUND_HALF_UP,
5533n/a 'context': P.getcontext()}}
5534n/a
5535n/a def mkargs(module, sig):
5536n/a args = []
5537n/a kwargs = {}
5538n/a for name, param in sig.parameters.items():
5539n/a if name == 'self': continue
5540n/a if param.kind == POS:
5541n/a args.append(pdict[module][name])
5542n/a elif param.kind == POS_KWD:
5543n/a kwargs[name] = pdict[module][name]
5544n/a else:
5545n/a raise TestFailed("unexpected parameter kind")
5546n/a return args, kwargs
5547n/a
5548n/a def tr(s):
5549n/a """The C Context docstrings use 'x' in order to prevent confusion
5550n/a with the article 'a' in the descriptions."""
5551n/a if s == 'x': return 'a'
5552n/a if s == 'y': return 'b'
5553n/a if s == 'z': return 'c'
5554n/a return s
5555n/a
5556n/a def doit(ty):
5557n/a p_type = getattr(P, ty)
5558n/a c_type = getattr(C, ty)
5559n/a for attr in dir(p_type):
5560n/a if attr.startswith('_'):
5561n/a continue
5562n/a p_func = getattr(p_type, attr)
5563n/a c_func = getattr(c_type, attr)
5564n/a if inspect.isfunction(p_func):
5565n/a p_sig = inspect.signature(p_func)
5566n/a c_sig = inspect.signature(c_func)
5567n/a
5568n/a # parameter names:
5569n/a p_names = list(p_sig.parameters.keys())
5570n/a c_names = [tr(x) for x in c_sig.parameters.keys()]
5571n/a
5572n/a self.assertEqual(c_names, p_names,
5573n/a msg="parameter name mismatch in %s" % p_func)
5574n/a
5575n/a p_kind = [x.kind for x in p_sig.parameters.values()]
5576n/a c_kind = [x.kind for x in c_sig.parameters.values()]
5577n/a
5578n/a # 'self' parameter:
5579n/a self.assertIs(p_kind[0], POS_KWD)
5580n/a self.assertIs(c_kind[0], POS)
5581n/a
5582n/a # remaining parameters:
5583n/a if ty == 'Decimal':
5584n/a self.assertEqual(c_kind[1:], p_kind[1:],
5585n/a msg="parameter kind mismatch in %s" % p_func)
5586n/a else: # Context methods are positional only in the C version.
5587n/a self.assertEqual(len(c_kind), len(p_kind),
5588n/a msg="parameter kind mismatch in %s" % p_func)
5589n/a
5590n/a # Run the function:
5591n/a args, kwds = mkargs(C, c_sig)
5592n/a try:
5593n/a getattr(c_type(9), attr)(*args, **kwds)
5594n/a except Exception as err:
5595n/a raise TestFailed("invalid signature for %s: %s %s" % (c_func, args, kwds))
5596n/a
5597n/a args, kwds = mkargs(P, p_sig)
5598n/a try:
5599n/a getattr(p_type(9), attr)(*args, **kwds)
5600n/a except Exception as err:
5601n/a raise TestFailed("invalid signature for %s: %s %s" % (p_func, args, kwds))
5602n/a
5603n/a doit('Decimal')
5604n/a doit('Context')
5605n/a
5606n/a
5607n/aall_tests = [
5608n/a CExplicitConstructionTest, PyExplicitConstructionTest,
5609n/a CImplicitConstructionTest, PyImplicitConstructionTest,
5610n/a CFormatTest, PyFormatTest,
5611n/a CArithmeticOperatorsTest, PyArithmeticOperatorsTest,
5612n/a CThreadingTest, PyThreadingTest,
5613n/a CUsabilityTest, PyUsabilityTest,
5614n/a CPythonAPItests, PyPythonAPItests,
5615n/a CContextAPItests, PyContextAPItests,
5616n/a CContextWithStatement, PyContextWithStatement,
5617n/a CContextFlags, PyContextFlags,
5618n/a CSpecialContexts, PySpecialContexts,
5619n/a CContextInputValidation, PyContextInputValidation,
5620n/a CContextSubclassing, PyContextSubclassing,
5621n/a CCoverage, PyCoverage,
5622n/a CFunctionality, PyFunctionality,
5623n/a CWhitebox, PyWhitebox,
5624n/a CIBMTestCases, PyIBMTestCases,
5625n/a]
5626n/a
5627n/a# Delete C tests if _decimal.so is not present.
5628n/aif not C:
5629n/a all_tests = all_tests[1::2]
5630n/aelse:
5631n/a all_tests.insert(0, CheckAttributes)
5632n/a all_tests.insert(1, SignatureTest)
5633n/a
5634n/a
5635n/adef test_main(arith=None, verbose=None, todo_tests=None, debug=None):
5636n/a """ Execute the tests.
5637n/a
5638n/a Runs all arithmetic tests if arith is True or if the "decimal" resource
5639n/a is enabled in regrtest.py
5640n/a """
5641n/a
5642n/a init(C)
5643n/a init(P)
5644n/a global TEST_ALL, DEBUG
5645n/a TEST_ALL = arith if arith is not None else is_resource_enabled('decimal')
5646n/a DEBUG = debug
5647n/a
5648n/a if todo_tests is None:
5649n/a test_classes = all_tests
5650n/a else:
5651n/a test_classes = [CIBMTestCases, PyIBMTestCases]
5652n/a
5653n/a # Dynamically build custom test definition for each file in the test
5654n/a # directory and add the definitions to the DecimalTest class. This
5655n/a # procedure insures that new files do not get skipped.
5656n/a for filename in os.listdir(directory):
5657n/a if '.decTest' not in filename or filename.startswith("."):
5658n/a continue
5659n/a head, tail = filename.split('.')
5660n/a if todo_tests is not None and head not in todo_tests:
5661n/a continue
5662n/a tester = lambda self, f=filename: self.eval_file(directory + f)
5663n/a setattr(CIBMTestCases, 'test_' + head, tester)
5664n/a setattr(PyIBMTestCases, 'test_' + head, tester)
5665n/a del filename, head, tail, tester
5666n/a
5667n/a
5668n/a try:
5669n/a run_unittest(*test_classes)
5670n/a if todo_tests is None:
5671n/a from doctest import IGNORE_EXCEPTION_DETAIL
5672n/a savedecimal = sys.modules['decimal']
5673n/a if C:
5674n/a sys.modules['decimal'] = C
5675n/a run_doctest(C, verbose, optionflags=IGNORE_EXCEPTION_DETAIL)
5676n/a sys.modules['decimal'] = P
5677n/a run_doctest(P, verbose)
5678n/a sys.modules['decimal'] = savedecimal
5679n/a finally:
5680n/a if C: C.setcontext(ORIGINAL_CONTEXT[C])
5681n/a P.setcontext(ORIGINAL_CONTEXT[P])
5682n/a if not C:
5683n/a warnings.warn('C tests skipped: no module named _decimal.',
5684n/a UserWarning)
5685n/a if not orig_sys_decimal is sys.modules['decimal']:
5686n/a raise TestFailed("Internal error: unbalanced number of changes to "
5687n/a "sys.modules['decimal'].")
5688n/a
5689n/a
5690n/aif __name__ == '__main__':
5691n/a import optparse
5692n/a p = optparse.OptionParser("test_decimal.py [--debug] [{--skip | test1 [test2 [...]]}]")
5693n/a p.add_option('--debug', '-d', action='store_true', help='shows the test number and context before each test')
5694n/a p.add_option('--skip', '-s', action='store_true', help='skip over 90% of the arithmetic tests')
5695n/a (opt, args) = p.parse_args()
5696n/a
5697n/a if opt.skip:
5698n/a test_main(arith=False, verbose=True)
5699n/a elif args:
5700n/a test_main(arith=True, verbose=True, todo_tests=args, debug=opt.debug)
5701n/a else:
5702n/a test_main(arith=True, verbose=True)