1# Copyright (c) 2004 Python Software Foundation.
2# All rights reserved.
3
4# Written by Eric Price <eprice at tjhsst.edu>
5#    and Facundo Batista <facundo at taniquetil.com.ar>
6#    and Raymond Hettinger <python at rcn.com>
7#    and Aahz (aahz at pobox.com)
8#    and Tim Peters
9
10"""
11These are the test cases for the Decimal module.
12
13There are two groups of tests, Arithmetic and Behaviour. The former test
14the Decimal arithmetic using the tests provided by Mike Cowlishaw. The latter
15test the pythonic behaviour according to PEP 327.
16
17Cowlishaw's tests can be downloaded from:
18
19   http://speleotrove.com/decimal/dectest.zip
20
21This test module can be called from command line with one parameter (Arithmetic
22or Behaviour) to test each part, or without parameter to test both parts. If
23you're working through IDLE, you can import this test module and call test_main()
24with the corresponding argument.
25"""
26
27import math
28import os, sys
29import operator
30import pickle, copy
31import unittest
32from decimal import *
33import numbers
34from test.test_support import (run_unittest, run_doctest, requires_unicode, u,
35                               is_resource_enabled, check_py3k_warnings,
36                               run_with_locale)
37import random
38try:
39    import threading
40except ImportError:
41    threading = None
42
43# Useful Test Constant
44Signals = tuple(getcontext().flags.keys())
45
46# Signals ordered with respect to precedence: when an operation
47# produces multiple signals, signals occurring later in the list
48# should be handled before those occurring earlier in the list.
49OrderedSignals = (Clamped, Rounded, Inexact, Subnormal,
50                  Underflow, Overflow, DivisionByZero, InvalidOperation)
51
52# Tests are built around these assumed context defaults.
53# test_main() restores the original context.
54def init():
55    global ORIGINAL_CONTEXT
56    ORIGINAL_CONTEXT = getcontext().copy()
57    DefaultTestContext = Context(
58        prec = 9,
59        rounding = ROUND_HALF_EVEN,
60        traps = dict.fromkeys(Signals, 0)
61        )
62    setcontext(DefaultTestContext)
63
64# decorator for skipping tests on non-IEEE 754 platforms
65requires_IEEE_754 = unittest.skipUnless(
66    float.__getformat__("double").startswith("IEEE"),
67    "test requires IEEE 754 doubles")
68
69TESTDATADIR = 'decimaltestdata'
70if __name__ == '__main__':
71    file = sys.argv[0]
72else:
73    file = __file__
74testdir = os.path.dirname(file) or os.curdir
75directory = testdir + os.sep + TESTDATADIR + os.sep
76
77skip_expected = not os.path.isdir(directory)
78
79# list of individual .decTest test ids that correspond to tests that
80# we're skipping for one reason or another.
81skipped_test_ids = set([
82    # Skip implementation-specific scaleb tests.
83    'scbx164',
84    'scbx165',
85
86    # For some operations (currently exp, ln, log10, power), the decNumber
87    # reference implementation imposes additional restrictions on the context
88    # and operands.  These restrictions are not part of the specification;
89    # however, the effect of these restrictions does show up in some of the
90    # testcases.  We skip testcases that violate these restrictions, since
91    # Decimal behaves differently from decNumber for these testcases so these
92    # testcases would otherwise fail.
93    'expx901',
94    'expx902',
95    'expx903',
96    'expx905',
97    'lnx901',
98    'lnx902',
99    'lnx903',
100    'lnx905',
101    'logx901',
102    'logx902',
103    'logx903',
104    'logx905',
105    'powx1183',
106    'powx1184',
107    'powx4001',
108    'powx4002',
109    'powx4003',
110    'powx4005',
111    'powx4008',
112    'powx4010',
113    'powx4012',
114    'powx4014',
115    ])
116
117# Make sure it actually raises errors when not expected and caught in flags
118# Slower, since it runs some things several times.
119EXTENDEDERRORTEST = False
120
121#Map the test cases' error names to the actual errors
122ErrorNames = {'clamped' : Clamped,
123              'conversion_syntax' : InvalidOperation,
124              'division_by_zero' : DivisionByZero,
125              'division_impossible' : InvalidOperation,
126              'division_undefined' : InvalidOperation,
127              'inexact' : Inexact,
128              'invalid_context' : InvalidOperation,
129              'invalid_operation' : InvalidOperation,
130              'overflow' : Overflow,
131              'rounded' : Rounded,
132              'subnormal' : Subnormal,
133              'underflow' : Underflow}
134
135
136def Nonfunction(*args):
137    """Doesn't do anything."""
138    return None
139
140RoundingDict = {'ceiling' : ROUND_CEILING, #Maps test-case names to roundings.
141                'down' : ROUND_DOWN,
142                'floor' : ROUND_FLOOR,
143                'half_down' : ROUND_HALF_DOWN,
144                'half_even' : ROUND_HALF_EVEN,
145                'half_up' : ROUND_HALF_UP,
146                'up' : ROUND_UP,
147                '05up' : ROUND_05UP}
148
149# Name adapter to be able to change the Decimal and Context
150# interface without changing the test files from Cowlishaw
151nameAdapter = {'and':'logical_and',
152               'apply':'_apply',
153               'class':'number_class',
154               'comparesig':'compare_signal',
155               'comparetotal':'compare_total',
156               'comparetotmag':'compare_total_mag',
157               'copy':'copy_decimal',
158               'copyabs':'copy_abs',
159               'copynegate':'copy_negate',
160               'copysign':'copy_sign',
161               'divideint':'divide_int',
162               'invert':'logical_invert',
163               'iscanonical':'is_canonical',
164               'isfinite':'is_finite',
165               'isinfinite':'is_infinite',
166               'isnan':'is_nan',
167               'isnormal':'is_normal',
168               'isqnan':'is_qnan',
169               'issigned':'is_signed',
170               'issnan':'is_snan',
171               'issubnormal':'is_subnormal',
172               'iszero':'is_zero',
173               'maxmag':'max_mag',
174               'minmag':'min_mag',
175               'nextminus':'next_minus',
176               'nextplus':'next_plus',
177               'nexttoward':'next_toward',
178               'or':'logical_or',
179               'reduce':'normalize',
180               'remaindernear':'remainder_near',
181               'samequantum':'same_quantum',
182               'squareroot':'sqrt',
183               'toeng':'to_eng_string',
184               'tointegral':'to_integral_value',
185               'tointegralx':'to_integral_exact',
186               'tosci':'to_sci_string',
187               'xor':'logical_xor',
188              }
189
190# The following functions return True/False rather than a Decimal instance
191
192LOGICAL_FUNCTIONS = (
193    'is_canonical',
194    'is_finite',
195    'is_infinite',
196    'is_nan',
197    'is_normal',
198    'is_qnan',
199    'is_signed',
200    'is_snan',
201    'is_subnormal',
202    'is_zero',
203    'same_quantum',
204    )
205
206class DecimalTest(unittest.TestCase):
207    """Class which tests the Decimal class against the test cases.
208
209    Changed for unittest.
210    """
211    def setUp(self):
212        self.context = Context()
213        self.ignore_list = ['#']
214        # Basically, a # means return NaN InvalidOperation.
215        # Different from a sNaN in trim
216
217        self.ChangeDict = {'precision' : self.change_precision,
218                      'rounding' : self.change_rounding_method,
219                      'maxexponent' : self.change_max_exponent,
220                      'minexponent' : self.change_min_exponent,
221                      'clamp' : self.change_clamp}
222
223    def eval_file(self, file):
224        global skip_expected
225        if skip_expected:
226            raise unittest.SkipTest
227        with open(file) as f:
228            for line in f:
229                line = line.replace('\r\n', '').replace('\n', '')
230                #print line
231                try:
232                    t = self.eval_line(line)
233                except DecimalException as exception:
234                    #Exception raised where there shouldn't have been one.
235                    self.fail('Exception "'+exception.__class__.__name__ + '" raised on line '+line)
236
237
238    def eval_line(self, s):
239        if s.find(' -> ') >= 0 and s[:2] != '--' and not s.startswith('  --'):
240            s = (s.split('->')[0] + '->' +
241                 s.split('->')[1].split('--')[0]).strip()
242        else:
243            s = s.split('--')[0].strip()
244
245        for ignore in self.ignore_list:
246            if s.find(ignore) >= 0:
247                #print s.split()[0], 'NotImplemented--', ignore
248                return
249        if not s:
250            return
251        elif ':' in s:
252            return self.eval_directive(s)
253        else:
254            return self.eval_equation(s)
255
256    def eval_directive(self, s):
257        funct, value = map(lambda x: x.strip().lower(), s.split(':'))
258        if funct == 'rounding':
259            value = RoundingDict[value]
260        else:
261            try:
262                value = int(value)
263            except ValueError:
264                pass
265
266        funct = self.ChangeDict.get(funct, Nonfunction)
267        funct(value)
268
269    def eval_equation(self, s):
270        #global DEFAULT_PRECISION
271        #print DEFAULT_PRECISION
272
273        if not TEST_ALL and random.random() < 0.90:
274            return
275
276        try:
277            Sides = s.split('->')
278            L = Sides[0].strip().split()
279            id = L[0]
280            if DEBUG:
281                print "Test ", id,
282            funct = L[1].lower()
283            valstemp = L[2:]
284            L = Sides[1].strip().split()
285            ans = L[0]
286            exceptions = L[1:]
287        except (TypeError, AttributeError, IndexError):
288            raise InvalidOperation
289        def FixQuotes(val):
290            val = val.replace("''", 'SingleQuote').replace('""', 'DoubleQuote')
291            val = val.replace("'", '').replace('"', '')
292            val = val.replace('SingleQuote', "'").replace('DoubleQuote', '"')
293            return val
294
295        if id in skipped_test_ids:
296            return
297
298        fname = nameAdapter.get(funct, funct)
299        if fname == 'rescale':
300            return
301        funct = getattr(self.context, fname)
302        vals = []
303        conglomerate = ''
304        quote = 0
305        theirexceptions = [ErrorNames[x.lower()] for x in exceptions]
306
307        for exception in Signals:
308            self.context.traps[exception] = 1 #Catch these bugs...
309        for exception in theirexceptions:
310            self.context.traps[exception] = 0
311        for i, val in enumerate(valstemp):
312            if val.count("'") % 2 == 1:
313                quote = 1 - quote
314            if quote:
315                conglomerate = conglomerate + ' ' + val
316                continue
317            else:
318                val = conglomerate + val
319                conglomerate = ''
320            v = FixQuotes(val)
321            if fname in ('to_sci_string', 'to_eng_string'):
322                if EXTENDEDERRORTEST:
323                    for error in theirexceptions:
324                        self.context.traps[error] = 1
325                        try:
326                            funct(self.context.create_decimal(v))
327                        except error:
328                            pass
329                        except Signals, e:
330                            self.fail("Raised %s in %s when %s disabled" % \
331                                      (e, s, error))
332                        else:
333                            self.fail("Did not raise %s in %s" % (error, s))
334                        self.context.traps[error] = 0
335                v = self.context.create_decimal(v)
336            else:
337                v = Decimal(v, self.context)
338            vals.append(v)
339
340        ans = FixQuotes(ans)
341
342        if EXTENDEDERRORTEST and fname not in ('to_sci_string', 'to_eng_string'):
343            for error in theirexceptions:
344                self.context.traps[error] = 1
345                try:
346                    funct(*vals)
347                except error:
348                    pass
349                except Signals, e:
350                    self.fail("Raised %s in %s when %s disabled" % \
351                              (e, s, error))
352                else:
353                    self.fail("Did not raise %s in %s" % (error, s))
354                self.context.traps[error] = 0
355
356            # as above, but add traps cumulatively, to check precedence
357            ordered_errors = [e for e in OrderedSignals if e in theirexceptions]
358            for error in ordered_errors:
359                self.context.traps[error] = 1
360                try:
361                    funct(*vals)
362                except error:
363                    pass
364                except Signals, e:
365                    self.fail("Raised %s in %s; expected %s" %
366                              (type(e), s, error))
367                else:
368                    self.fail("Did not raise %s in %s" % (error, s))
369            # reset traps
370            for error in ordered_errors:
371                self.context.traps[error] = 0
372
373
374        if DEBUG:
375            print "--", self.context
376        try:
377            result = str(funct(*vals))
378            if fname in LOGICAL_FUNCTIONS:
379                result = str(int(eval(result))) # 'True', 'False' -> '1', '0'
380        except Signals, error:
381            self.fail("Raised %s in %s" % (error, s))
382        except: #Catch any error long enough to state the test case.
383            print "ERROR:", s
384            raise
385
386        myexceptions = self.getexceptions()
387        self.context.clear_flags()
388
389        self.assertEqual(result, ans,
390                         'Incorrect answer for ' + s + ' -- got ' + result)
391        self.assertItemsEqual(myexceptions, theirexceptions,
392              'Incorrect flags set in ' + s + ' -- got ' + str(myexceptions))
393
394    def getexceptions(self):
395        return [e for e in Signals if self.context.flags[e]]
396
397    def change_precision(self, prec):
398        self.context.prec = prec
399    def change_rounding_method(self, rounding):
400        self.context.rounding = rounding
401    def change_min_exponent(self, exp):
402        self.context.Emin = exp
403    def change_max_exponent(self, exp):
404        self.context.Emax = exp
405    def change_clamp(self, clamp):
406        self.context._clamp = clamp
407
408
409
410# The following classes test the behaviour of Decimal according to PEP 327
411
412class DecimalExplicitConstructionTest(unittest.TestCase):
413    '''Unit tests for Explicit Construction cases of Decimal.'''
414
415    def test_explicit_empty(self):
416        self.assertEqual(Decimal(), Decimal("0"))
417
418    def test_explicit_from_None(self):
419        self.assertRaises(TypeError, Decimal, None)
420
421    def test_explicit_from_int(self):
422
423        #positive
424        d = Decimal(45)
425        self.assertEqual(str(d), '45')
426
427        #very large positive
428        d = Decimal(500000123)
429        self.assertEqual(str(d), '500000123')
430
431        #negative
432        d = Decimal(-45)
433        self.assertEqual(str(d), '-45')
434
435        #zero
436        d = Decimal(0)
437        self.assertEqual(str(d), '0')
438
439    def test_explicit_from_string(self):
440
441        #empty
442        self.assertEqual(str(Decimal('')), 'NaN')
443
444        #int
445        self.assertEqual(str(Decimal('45')), '45')
446
447        #float
448        self.assertEqual(str(Decimal('45.34')), '45.34')
449
450        #engineer notation
451        self.assertEqual(str(Decimal('45e2')), '4.5E+3')
452
453        #just not a number
454        self.assertEqual(str(Decimal('ugly')), 'NaN')
455
456        #leading and trailing whitespace permitted
457        self.assertEqual(str(Decimal('1.3E4 \n')), '1.3E+4')
458        self.assertEqual(str(Decimal('  -7.89')), '-7.89')
459
460        #unicode strings should be permitted
461        self.assertEqual(str(Decimal(u'0E-017')), '0E-17')
462        self.assertEqual(str(Decimal(u'45')), '45')
463        self.assertEqual(str(Decimal(u'-Inf')), '-Infinity')
464        self.assertEqual(str(Decimal(u'NaN123')), 'NaN123')
465
466    def test_explicit_from_tuples(self):
467
468        #zero
469        d = Decimal( (0, (0,), 0) )
470        self.assertEqual(str(d), '0')
471
472        #int
473        d = Decimal( (1, (4, 5), 0) )
474        self.assertEqual(str(d), '-45')
475
476        #float
477        d = Decimal( (0, (4, 5, 3, 4), -2) )
478        self.assertEqual(str(d), '45.34')
479
480        #weird
481        d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
482        self.assertEqual(str(d), '-4.34913534E-17')
483
484        #wrong number of items
485        self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1)) )
486
487        #bad sign
488        self.assertRaises(ValueError, Decimal, (8, (4, 3, 4, 9, 1), 2) )
489        self.assertRaises(ValueError, Decimal, (0., (4, 3, 4, 9, 1), 2) )
490        self.assertRaises(ValueError, Decimal, (Decimal(1), (4, 3, 4, 9, 1), 2))
491
492        #bad exp
493        self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), 'wrong!') )
494        self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), 0.) )
495        self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), '1') )
496
497        #bad coefficients
498        self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, None, 1), 2) )
499        self.assertRaises(ValueError, Decimal, (1, (4, -3, 4, 9, 1), 2) )
500        self.assertRaises(ValueError, Decimal, (1, (4, 10, 4, 9, 1), 2) )
501        self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 'a', 1), 2) )
502
503    def test_explicit_from_bool(self):
504        self.assertIs(bool(Decimal(0)), False)
505        self.assertIs(bool(Decimal(1)), True)
506        self.assertEqual(Decimal(False), Decimal(0))
507        self.assertEqual(Decimal(True), Decimal(1))
508
509    def test_explicit_from_Decimal(self):
510
511        #positive
512        d = Decimal(45)
513        e = Decimal(d)
514        self.assertEqual(str(e), '45')
515        self.assertNotEqual(id(d), id(e))
516
517        #very large positive
518        d = Decimal(500000123)
519        e = Decimal(d)
520        self.assertEqual(str(e), '500000123')
521        self.assertNotEqual(id(d), id(e))
522
523        #negative
524        d = Decimal(-45)
525        e = Decimal(d)
526        self.assertEqual(str(e), '-45')
527        self.assertNotEqual(id(d), id(e))
528
529        #zero
530        d = Decimal(0)
531        e = Decimal(d)
532        self.assertEqual(str(e), '0')
533        self.assertNotEqual(id(d), id(e))
534
535    @requires_IEEE_754
536    def test_explicit_from_float(self):
537        r = Decimal(0.1)
538        self.assertEqual(type(r), Decimal)
539        self.assertEqual(str(r),
540                '0.1000000000000000055511151231257827021181583404541015625')
541        self.assertTrue(Decimal(float('nan')).is_qnan())
542        self.assertTrue(Decimal(float('inf')).is_infinite())
543        self.assertTrue(Decimal(float('-inf')).is_infinite())
544        self.assertEqual(str(Decimal(float('nan'))),
545                         str(Decimal('NaN')))
546        self.assertEqual(str(Decimal(float('inf'))),
547                         str(Decimal('Infinity')))
548        self.assertEqual(str(Decimal(float('-inf'))),
549                         str(Decimal('-Infinity')))
550        self.assertEqual(str(Decimal(float('-0.0'))),
551                         str(Decimal('-0')))
552        for i in range(200):
553            x = random.expovariate(0.01) * (random.random() * 2.0 - 1.0)
554            self.assertEqual(x, float(Decimal(x))) # roundtrip
555
556    def test_explicit_context_create_decimal(self):
557
558        nc = copy.copy(getcontext())
559        nc.prec = 3
560
561        # empty
562        d = Decimal()
563        self.assertEqual(str(d), '0')
564        d = nc.create_decimal()
565        self.assertEqual(str(d), '0')
566
567        # from None
568        self.assertRaises(TypeError, nc.create_decimal, None)
569
570        # from int
571        d = nc.create_decimal(456)
572        self.assertIsInstance(d, Decimal)
573        self.assertEqual(nc.create_decimal(45678),
574                         nc.create_decimal('457E+2'))
575
576        # from string
577        d = Decimal('456789')
578        self.assertEqual(str(d), '456789')
579        d = nc.create_decimal('456789')
580        self.assertEqual(str(d), '4.57E+5')
581        # leading and trailing whitespace should result in a NaN;
582        # spaces are already checked in Cowlishaw's test-suite, so
583        # here we just check that a trailing newline results in a NaN
584        self.assertEqual(str(nc.create_decimal('3.14\n')), 'NaN')
585
586        # from tuples
587        d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
588        self.assertEqual(str(d), '-4.34913534E-17')
589        d = nc.create_decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
590        self.assertEqual(str(d), '-4.35E-17')
591
592        # from Decimal
593        prevdec = Decimal(500000123)
594        d = Decimal(prevdec)
595        self.assertEqual(str(d), '500000123')
596        d = nc.create_decimal(prevdec)
597        self.assertEqual(str(d), '5.00E+8')
598
599    @requires_unicode
600    def test_unicode_digits(self):
601        test_values = {
602            u(r'\uff11'): '1',
603            u(r'\u0660.\u0660\u0663\u0667\u0662e-\u0663') : '0.0000372',
604            u(r'-nan\u0c68\u0c6a\u0c66\u0c66') : '-NaN2400',
605            }
606        for input, expected in test_values.items():
607            self.assertEqual(str(Decimal(input)), expected)
608
609
610class DecimalImplicitConstructionTest(unittest.TestCase):
611    '''Unit tests for Implicit Construction cases of Decimal.'''
612
613    def test_implicit_from_None(self):
614        self.assertRaises(TypeError, eval, 'Decimal(5) + None', globals())
615
616    def test_implicit_from_int(self):
617        #normal
618        self.assertEqual(str(Decimal(5) + 45), '50')
619        #exceeding precision
620        self.assertEqual(Decimal(5) + 123456789000, Decimal(123456789000))
621
622    def test_implicit_from_string(self):
623        self.assertRaises(TypeError, eval, 'Decimal(5) + "3"', globals())
624
625    def test_implicit_from_float(self):
626        self.assertRaises(TypeError, eval, 'Decimal(5) + 2.2', globals())
627
628    def test_implicit_from_Decimal(self):
629        self.assertEqual(Decimal(5) + Decimal(45), Decimal(50))
630
631    def test_rop(self):
632        # Allow other classes to be trained to interact with Decimals
633        class E:
634            def __divmod__(self, other):
635                return 'divmod ' + str(other)
636            def __rdivmod__(self, other):
637                return str(other) + ' rdivmod'
638            def __lt__(self, other):
639                return 'lt ' + str(other)
640            def __gt__(self, other):
641                return 'gt ' + str(other)
642            def __le__(self, other):
643                return 'le ' + str(other)
644            def __ge__(self, other):
645                return 'ge ' + str(other)
646            def __eq__(self, other):
647                return 'eq ' + str(other)
648            def __ne__(self, other):
649                return 'ne ' + str(other)
650
651        self.assertEqual(divmod(E(), Decimal(10)), 'divmod 10')
652        self.assertEqual(divmod(Decimal(10), E()), '10 rdivmod')
653        self.assertEqual(eval('Decimal(10) < E()'), 'gt 10')
654        self.assertEqual(eval('Decimal(10) > E()'), 'lt 10')
655        self.assertEqual(eval('Decimal(10) <= E()'), 'ge 10')
656        self.assertEqual(eval('Decimal(10) >= E()'), 'le 10')
657        self.assertEqual(eval('Decimal(10) == E()'), 'eq 10')
658        self.assertEqual(eval('Decimal(10) != E()'), 'ne 10')
659
660        # insert operator methods and then exercise them
661        oplist = [
662            ('+', '__add__', '__radd__'),
663            ('-', '__sub__', '__rsub__'),
664            ('*', '__mul__', '__rmul__'),
665            ('%', '__mod__', '__rmod__'),
666            ('//', '__floordiv__', '__rfloordiv__'),
667            ('**', '__pow__', '__rpow__')
668        ]
669        with check_py3k_warnings():
670            if 1 / 2 == 0:
671                # testing with classic division, so add __div__
672                oplist.append(('/', '__div__', '__rdiv__'))
673            else:
674                # testing with -Qnew, so add __truediv__
675                oplist.append(('/', '__truediv__', '__rtruediv__'))
676
677        for sym, lop, rop in oplist:
678            setattr(E, lop, lambda self, other: 'str' + lop + str(other))
679            setattr(E, rop, lambda self, other: str(other) + rop + 'str')
680            self.assertEqual(eval('E()' + sym + 'Decimal(10)'),
681                             'str' + lop + '10')
682            self.assertEqual(eval('Decimal(10)' + sym + 'E()'),
683                             '10' + rop + 'str')
684
685
686class DecimalFormatTest(unittest.TestCase):
687    '''Unit tests for the format function.'''
688    def test_formatting(self):
689        # triples giving a format, a Decimal, and the expected result
690        test_values = [
691            ('e', '0E-15', '0e-15'),
692            ('e', '2.3E-15', '2.3e-15'),
693            ('e', '2.30E+2', '2.30e+2'), # preserve significant zeros
694            ('e', '2.30000E-15', '2.30000e-15'),
695            ('e', '1.23456789123456789e40', '1.23456789123456789e+40'),
696            ('e', '1.5', '1.5e+0'),
697            ('e', '0.15', '1.5e-1'),
698            ('e', '0.015', '1.5e-2'),
699            ('e', '0.0000000000015', '1.5e-12'),
700            ('e', '15.0', '1.50e+1'),
701            ('e', '-15', '-1.5e+1'),
702            ('e', '0', '0e+0'),
703            ('e', '0E1', '0e+1'),
704            ('e', '0.0', '0e-1'),
705            ('e', '0.00', '0e-2'),
706            ('.6e', '0E-15', '0.000000e-9'),
707            ('.6e', '0', '0.000000e+6'),
708            ('.6e', '9.999999', '9.999999e+0'),
709            ('.6e', '9.9999999', '1.000000e+1'),
710            ('.6e', '-1.23e5', '-1.230000e+5'),
711            ('.6e', '1.23456789e-3', '1.234568e-3'),
712            ('f', '0', '0'),
713            ('f', '0.0', '0.0'),
714            ('f', '0E-2', '0.00'),
715            ('f', '0.00E-8', '0.0000000000'),
716            ('f', '0E1', '0'), # loses exponent information
717            ('f', '3.2E1', '32'),
718            ('f', '3.2E2', '320'),
719            ('f', '3.20E2', '320'),
720            ('f', '3.200E2', '320.0'),
721            ('f', '3.2E-6', '0.0000032'),
722            ('.6f', '0E-15', '0.000000'), # all zeros treated equally
723            ('.6f', '0E1', '0.000000'),
724            ('.6f', '0', '0.000000'),
725            ('.0f', '0', '0'), # no decimal point
726            ('.0f', '0e-2', '0'),
727            ('.0f', '3.14159265', '3'),
728            ('.1f', '3.14159265', '3.1'),
729            ('.4f', '3.14159265', '3.1416'),
730            ('.6f', '3.14159265', '3.141593'),
731            ('.7f', '3.14159265', '3.1415926'), # round-half-even!
732            ('.8f', '3.14159265', '3.14159265'),
733            ('.9f', '3.14159265', '3.141592650'),
734
735            ('g', '0', '0'),
736            ('g', '0.0', '0.0'),
737            ('g', '0E1', '0e+1'),
738            ('G', '0E1', '0E+1'),
739            ('g', '0E-5', '0.00000'),
740            ('g', '0E-6', '0.000000'),
741            ('g', '0E-7', '0e-7'),
742            ('g', '-0E2', '-0e+2'),
743            ('.0g', '3.14159265', '3'),  # 0 sig fig -> 1 sig fig
744            ('.1g', '3.14159265', '3'),
745            ('.2g', '3.14159265', '3.1'),
746            ('.5g', '3.14159265', '3.1416'),
747            ('.7g', '3.14159265', '3.141593'),
748            ('.8g', '3.14159265', '3.1415926'), # round-half-even!
749            ('.9g', '3.14159265', '3.14159265'),
750            ('.10g', '3.14159265', '3.14159265'), # don't pad
751
752            ('%', '0E1', '0%'),
753            ('%', '0E0', '0%'),
754            ('%', '0E-1', '0%'),
755            ('%', '0E-2', '0%'),
756            ('%', '0E-3', '0.0%'),
757            ('%', '0E-4', '0.00%'),
758
759            ('.3%', '0', '0.000%'), # all zeros treated equally
760            ('.3%', '0E10', '0.000%'),
761            ('.3%', '0E-10', '0.000%'),
762            ('.3%', '2.34', '234.000%'),
763            ('.3%', '1.234567', '123.457%'),
764            ('.0%', '1.23', '123%'),
765
766            ('e', 'NaN', 'NaN'),
767            ('f', '-NaN123', '-NaN123'),
768            ('+g', 'NaN456', '+NaN456'),
769            ('.3e', 'Inf', 'Infinity'),
770            ('.16f', '-Inf', '-Infinity'),
771            ('.0g', '-sNaN', '-sNaN'),
772
773            ('', '1.00', '1.00'),
774
775            # test alignment and padding
776            ('6', '123', '   123'),
777            ('<6', '123', '123   '),
778            ('>6', '123', '   123'),
779            ('^6', '123', ' 123  '),
780            ('=+6', '123', '+  123'),
781            ('#<10', 'NaN', 'NaN#######'),
782            ('#<10', '-4.3', '-4.3######'),
783            ('#<+10', '0.0130', '+0.0130###'),
784            ('#< 10', '0.0130', ' 0.0130###'),
785            ('@>10', '-Inf', '@-Infinity'),
786            ('#>5', '-Inf', '-Infinity'),
787            ('?^5', '123', '?123?'),
788            ('%^6', '123', '%123%%'),
789            (' ^6', '-45.6', '-45.6 '),
790            ('/=10', '-45.6', '-/////45.6'),
791            ('/=+10', '45.6', '+/////45.6'),
792            ('/= 10', '45.6', ' /////45.6'),
793
794            # thousands separator
795            (',', '1234567', '1,234,567'),
796            (',', '123456', '123,456'),
797            (',', '12345', '12,345'),
798            (',', '1234', '1,234'),
799            (',', '123', '123'),
800            (',', '12', '12'),
801            (',', '1', '1'),
802            (',', '0', '0'),
803            (',', '-1234567', '-1,234,567'),
804            (',', '-123456', '-123,456'),
805            ('7,', '123456', '123,456'),
806            ('8,', '123456', ' 123,456'),
807            ('08,', '123456', '0,123,456'), # special case: extra 0 needed
808            ('+08,', '123456', '+123,456'), # but not if there's a sign
809            (' 08,', '123456', ' 123,456'),
810            ('08,', '-123456', '-123,456'),
811            ('+09,', '123456', '+0,123,456'),
812            # ... with fractional part...
813            ('07,', '1234.56', '1,234.56'),
814            ('08,', '1234.56', '1,234.56'),
815            ('09,', '1234.56', '01,234.56'),
816            ('010,', '1234.56', '001,234.56'),
817            ('011,', '1234.56', '0,001,234.56'),
818            ('012,', '1234.56', '0,001,234.56'),
819            ('08,.1f', '1234.5', '01,234.5'),
820            # no thousands separators in fraction part
821            (',', '1.23456789', '1.23456789'),
822            (',%', '123.456789', '12,345.6789%'),
823            (',e', '123456', '1.23456e+5'),
824            (',E', '123456', '1.23456E+5'),
825
826            # issue 6850
827            ('a=-7.0', '0.12345', 'aaaa0.1'),
828
829            # issue 22090
830            ('<^+15.20%', 'inf', '<<+Infinity%<<<'),
831            ('\x07>,%', 'sNaN1234567', 'sNaN1234567%'),
832            ('=10.10%', 'NaN123', '   NaN123%'),
833            ]
834        for fmt, d, result in test_values:
835            self.assertEqual(format(Decimal(d), fmt), result)
836
837    def test_n_format(self):
838        try:
839            from locale import CHAR_MAX
840        except ImportError:
841            self.skipTest('locale.CHAR_MAX not available')
842
843        # Set up some localeconv-like dictionaries
844        en_US = {
845            'decimal_point' : '.',
846            'grouping' : [3, 3, 0],
847            'thousands_sep': ','
848            }
849
850        fr_FR = {
851            'decimal_point' : ',',
852            'grouping' : [CHAR_MAX],
853            'thousands_sep' : ''
854            }
855
856        ru_RU = {
857            'decimal_point' : ',',
858            'grouping' : [3, 3, 0],
859            'thousands_sep' : ' '
860            }
861
862        crazy = {
863            'decimal_point' : '&',
864            'grouping' : [1, 4, 2, CHAR_MAX],
865            'thousands_sep' : '-'
866            }
867
868
869        def get_fmt(x, locale, fmt='n'):
870            return Decimal.__format__(Decimal(x), fmt, _localeconv=locale)
871
872        self.assertEqual(get_fmt(Decimal('12.7'), en_US), '12.7')
873        self.assertEqual(get_fmt(Decimal('12.7'), fr_FR), '12,7')
874        self.assertEqual(get_fmt(Decimal('12.7'), ru_RU), '12,7')
875        self.assertEqual(get_fmt(Decimal('12.7'), crazy), '1-2&7')
876
877        self.assertEqual(get_fmt(123456789, en_US), '123,456,789')
878        self.assertEqual(get_fmt(123456789, fr_FR), '123456789')
879        self.assertEqual(get_fmt(123456789, ru_RU), '123 456 789')
880        self.assertEqual(get_fmt(1234567890123, crazy), '123456-78-9012-3')
881
882        self.assertEqual(get_fmt(123456789, en_US, '.6n'), '1.23457e+8')
883        self.assertEqual(get_fmt(123456789, fr_FR, '.6n'), '1,23457e+8')
884        self.assertEqual(get_fmt(123456789, ru_RU, '.6n'), '1,23457e+8')
885        self.assertEqual(get_fmt(123456789, crazy, '.6n'), '1&23457e+8')
886
887        # zero padding
888        self.assertEqual(get_fmt(1234, fr_FR, '03n'), '1234')
889        self.assertEqual(get_fmt(1234, fr_FR, '04n'), '1234')
890        self.assertEqual(get_fmt(1234, fr_FR, '05n'), '01234')
891        self.assertEqual(get_fmt(1234, fr_FR, '06n'), '001234')
892
893        self.assertEqual(get_fmt(12345, en_US, '05n'), '12,345')
894        self.assertEqual(get_fmt(12345, en_US, '06n'), '12,345')
895        self.assertEqual(get_fmt(12345, en_US, '07n'), '012,345')
896        self.assertEqual(get_fmt(12345, en_US, '08n'), '0,012,345')
897        self.assertEqual(get_fmt(12345, en_US, '09n'), '0,012,345')
898        self.assertEqual(get_fmt(12345, en_US, '010n'), '00,012,345')
899
900        self.assertEqual(get_fmt(123456, crazy, '06n'), '1-2345-6')
901        self.assertEqual(get_fmt(123456, crazy, '07n'), '1-2345-6')
902        self.assertEqual(get_fmt(123456, crazy, '08n'), '1-2345-6')
903        self.assertEqual(get_fmt(123456, crazy, '09n'), '01-2345-6')
904        self.assertEqual(get_fmt(123456, crazy, '010n'), '0-01-2345-6')
905        self.assertEqual(get_fmt(123456, crazy, '011n'), '0-01-2345-6')
906        self.assertEqual(get_fmt(123456, crazy, '012n'), '00-01-2345-6')
907        self.assertEqual(get_fmt(123456, crazy, '013n'), '000-01-2345-6')
908
909    @run_with_locale('LC_ALL', 'ps_AF.UTF-8')
910    def test_wide_char_separator_decimal_point(self):
911        # locale with wide char separator and decimal point
912        import locale
913
914        decimal_point = locale.localeconv()['decimal_point']
915        thousands_sep = locale.localeconv()['thousands_sep']
916        if decimal_point != '\xd9\xab':
917            self.skipTest('inappropriate decimal point separator '
918                          '({!r} not {!r})'.format(decimal_point, '\xd9\xab'))
919        if thousands_sep != '\xd9\xac':
920            self.skipTest('inappropriate thousands separator '
921                          '({!r} not {!r})'.format(thousands_sep, '\xd9\xac'))
922
923        self.assertEqual(format(Decimal('100000000.123'), 'n'),
924                         '100\xd9\xac000\xd9\xac000\xd9\xab123')
925
926
927class DecimalArithmeticOperatorsTest(unittest.TestCase):
928    '''Unit tests for all arithmetic operators, binary and unary.'''
929
930    def test_addition(self):
931
932        d1 = Decimal('-11.1')
933        d2 = Decimal('22.2')
934
935        #two Decimals
936        self.assertEqual(d1+d2, Decimal('11.1'))
937        self.assertEqual(d2+d1, Decimal('11.1'))
938
939        #with other type, left
940        c = d1 + 5
941        self.assertEqual(c, Decimal('-6.1'))
942        self.assertEqual(type(c), type(d1))
943
944        #with other type, right
945        c = 5 + d1
946        self.assertEqual(c, Decimal('-6.1'))
947        self.assertEqual(type(c), type(d1))
948
949        #inline with decimal
950        d1 += d2
951        self.assertEqual(d1, Decimal('11.1'))
952
953        #inline with other type
954        d1 += 5
955        self.assertEqual(d1, Decimal('16.1'))
956
957    def test_subtraction(self):
958
959        d1 = Decimal('-11.1')
960        d2 = Decimal('22.2')
961
962        #two Decimals
963        self.assertEqual(d1-d2, Decimal('-33.3'))
964        self.assertEqual(d2-d1, Decimal('33.3'))
965
966        #with other type, left
967        c = d1 - 5
968        self.assertEqual(c, Decimal('-16.1'))
969        self.assertEqual(type(c), type(d1))
970
971        #with other type, right
972        c = 5 - d1
973        self.assertEqual(c, Decimal('16.1'))
974        self.assertEqual(type(c), type(d1))
975
976        #inline with decimal
977        d1 -= d2
978        self.assertEqual(d1, Decimal('-33.3'))
979
980        #inline with other type
981        d1 -= 5
982        self.assertEqual(d1, Decimal('-38.3'))
983
984    def test_multiplication(self):
985
986        d1 = Decimal('-5')
987        d2 = Decimal('3')
988
989        #two Decimals
990        self.assertEqual(d1*d2, Decimal('-15'))
991        self.assertEqual(d2*d1, Decimal('-15'))
992
993        #with other type, left
994        c = d1 * 5
995        self.assertEqual(c, Decimal('-25'))
996        self.assertEqual(type(c), type(d1))
997
998        #with other type, right
999        c = 5 * d1
1000        self.assertEqual(c, Decimal('-25'))
1001        self.assertEqual(type(c), type(d1))
1002
1003        #inline with decimal
1004        d1 *= d2
1005        self.assertEqual(d1, Decimal('-15'))
1006
1007        #inline with other type
1008        d1 *= 5
1009        self.assertEqual(d1, Decimal('-75'))
1010
1011    def test_division(self):
1012
1013        d1 = Decimal('-5')
1014        d2 = Decimal('2')
1015
1016        #two Decimals
1017        self.assertEqual(d1/d2, Decimal('-2.5'))
1018        self.assertEqual(d2/d1, Decimal('-0.4'))
1019
1020        #with other type, left
1021        c = d1 / 4
1022        self.assertEqual(c, Decimal('-1.25'))
1023        self.assertEqual(type(c), type(d1))
1024
1025        #with other type, right
1026        c = 4 / d1
1027        self.assertEqual(c, Decimal('-0.8'))
1028        self.assertEqual(type(c), type(d1))
1029
1030        #inline with decimal
1031        d1 /= d2
1032        self.assertEqual(d1, Decimal('-2.5'))
1033
1034        #inline with other type
1035        d1 /= 4
1036        self.assertEqual(d1, Decimal('-0.625'))
1037
1038    def test_floor_division(self):
1039
1040        d1 = Decimal('5')
1041        d2 = Decimal('2')
1042
1043        #two Decimals
1044        self.assertEqual(d1//d2, Decimal('2'))
1045        self.assertEqual(d2//d1, Decimal('0'))
1046
1047        #with other type, left
1048        c = d1 // 4
1049        self.assertEqual(c, Decimal('1'))
1050        self.assertEqual(type(c), type(d1))
1051
1052        #with other type, right
1053        c = 7 // d1
1054        self.assertEqual(c, Decimal('1'))
1055        self.assertEqual(type(c), type(d1))
1056
1057        #inline with decimal
1058        d1 //= d2
1059        self.assertEqual(d1, Decimal('2'))
1060
1061        #inline with other type
1062        d1 //= 2
1063        self.assertEqual(d1, Decimal('1'))
1064
1065    def test_powering(self):
1066
1067        d1 = Decimal('5')
1068        d2 = Decimal('2')
1069
1070        #two Decimals
1071        self.assertEqual(d1**d2, Decimal('25'))
1072        self.assertEqual(d2**d1, Decimal('32'))
1073
1074        #with other type, left
1075        c = d1 ** 4
1076        self.assertEqual(c, Decimal('625'))
1077        self.assertEqual(type(c), type(d1))
1078
1079        #with other type, right
1080        c = 7 ** d1
1081        self.assertEqual(c, Decimal('16807'))
1082        self.assertEqual(type(c), type(d1))
1083
1084        #inline with decimal
1085        d1 **= d2
1086        self.assertEqual(d1, Decimal('25'))
1087
1088        #inline with other type
1089        d1 **= 4
1090        self.assertEqual(d1, Decimal('390625'))
1091
1092    def test_module(self):
1093
1094        d1 = Decimal('5')
1095        d2 = Decimal('2')
1096
1097        #two Decimals
1098        self.assertEqual(d1%d2, Decimal('1'))
1099        self.assertEqual(d2%d1, Decimal('2'))
1100
1101        #with other type, left
1102        c = d1 % 4
1103        self.assertEqual(c, Decimal('1'))
1104        self.assertEqual(type(c), type(d1))
1105
1106        #with other type, right
1107        c = 7 % d1
1108        self.assertEqual(c, Decimal('2'))
1109        self.assertEqual(type(c), type(d1))
1110
1111        #inline with decimal
1112        d1 %= d2
1113        self.assertEqual(d1, Decimal('1'))
1114
1115        #inline with other type
1116        d1 %= 4
1117        self.assertEqual(d1, Decimal('1'))
1118
1119    def test_floor_div_module(self):
1120
1121        d1 = Decimal('5')
1122        d2 = Decimal('2')
1123
1124        #two Decimals
1125        (p, q) = divmod(d1, d2)
1126        self.assertEqual(p, Decimal('2'))
1127        self.assertEqual(q, Decimal('1'))
1128        self.assertEqual(type(p), type(d1))
1129        self.assertEqual(type(q), type(d1))
1130
1131        #with other type, left
1132        (p, q) = divmod(d1, 4)
1133        self.assertEqual(p, Decimal('1'))
1134        self.assertEqual(q, Decimal('1'))
1135        self.assertEqual(type(p), type(d1))
1136        self.assertEqual(type(q), type(d1))
1137
1138        #with other type, right
1139        (p, q) = divmod(7, d1)
1140        self.assertEqual(p, Decimal('1'))
1141        self.assertEqual(q, Decimal('2'))
1142        self.assertEqual(type(p), type(d1))
1143        self.assertEqual(type(q), type(d1))
1144
1145    def test_unary_operators(self):
1146        self.assertEqual(+Decimal(45), Decimal(+45))           #  +
1147        self.assertEqual(-Decimal(45), Decimal(-45))           #  -
1148        self.assertEqual(abs(Decimal(45)), abs(Decimal(-45)))  # abs
1149
1150    def test_nan_comparisons(self):
1151        # comparisons involving signaling nans signal InvalidOperation
1152
1153        # order comparisons (<, <=, >, >=) involving only quiet nans
1154        # also signal InvalidOperation
1155
1156        # equality comparisons (==, !=) involving only quiet nans
1157        # don't signal, but return False or True respectively.
1158
1159        n = Decimal('NaN')
1160        s = Decimal('sNaN')
1161        i = Decimal('Inf')
1162        f = Decimal('2')
1163
1164        qnan_pairs = (n, n), (n, i), (i, n), (n, f), (f, n)
1165        snan_pairs = (s, n), (n, s), (s, i), (i, s), (s, f), (f, s), (s, s)
1166        order_ops = operator.lt, operator.le, operator.gt, operator.ge
1167        equality_ops = operator.eq, operator.ne
1168
1169        # results when InvalidOperation is not trapped
1170        for x, y in qnan_pairs + snan_pairs:
1171            for op in order_ops + equality_ops:
1172                got = op(x, y)
1173                expected = True if op is operator.ne else False
1174                self.assertIs(expected, got,
1175                              "expected {0!r} for operator.{1}({2!r}, {3!r}); "
1176                              "got {4!r}".format(
1177                        expected, op.__name__, x, y, got))
1178
1179        # repeat the above, but this time trap the InvalidOperation
1180        with localcontext() as ctx:
1181            ctx.traps[InvalidOperation] = 1
1182
1183            for x, y in qnan_pairs:
1184                for op in equality_ops:
1185                    got = op(x, y)
1186                    expected = True if op is operator.ne else False
1187                    self.assertIs(expected, got,
1188                                  "expected {0!r} for "
1189                                  "operator.{1}({2!r}, {3!r}); "
1190                                  "got {4!r}".format(
1191                            expected, op.__name__, x, y, got))
1192
1193            for x, y in snan_pairs:
1194                for op in equality_ops:
1195                    self.assertRaises(InvalidOperation, operator.eq, x, y)
1196                    self.assertRaises(InvalidOperation, operator.ne, x, y)
1197
1198            for x, y in qnan_pairs + snan_pairs:
1199                for op in order_ops:
1200                    self.assertRaises(InvalidOperation, op, x, y)
1201
1202    def test_copy_sign(self):
1203        d = Decimal(1).copy_sign(Decimal(-2))
1204
1205        self.assertEqual(Decimal(1).copy_sign(-2), d)
1206        self.assertRaises(TypeError, Decimal(1).copy_sign, '-2')
1207
1208# The following are two functions used to test threading in the next class
1209
1210def thfunc1(cls):
1211    d1 = Decimal(1)
1212    d3 = Decimal(3)
1213    test1 = d1/d3
1214    cls.synchro.wait()
1215    test2 = d1/d3
1216    cls.finish1.set()
1217
1218    cls.assertEqual(test1, Decimal('0.3333333333333333333333333333'))
1219    cls.assertEqual(test2, Decimal('0.3333333333333333333333333333'))
1220
1221def thfunc2(cls):
1222    d1 = Decimal(1)
1223    d3 = Decimal(3)
1224    test1 = d1/d3
1225    thiscontext = getcontext()
1226    thiscontext.prec = 18
1227    test2 = d1/d3
1228    cls.synchro.set()
1229    cls.finish2.set()
1230
1231    cls.assertEqual(test1, Decimal('0.3333333333333333333333333333'))
1232    cls.assertEqual(test2, Decimal('0.333333333333333333'))
1233
1234
1235@unittest.skipUnless(threading, 'threading required')
1236class DecimalUseOfContextTest(unittest.TestCase):
1237    '''Unit tests for Use of Context cases in Decimal.'''
1238
1239    # Take care executing this test from IDLE, there's an issue in threading
1240    # that hangs IDLE and I couldn't find it
1241
1242    def test_threading(self):
1243        #Test the "threading isolation" of a Context.
1244
1245        self.synchro = threading.Event()
1246        self.finish1 = threading.Event()
1247        self.finish2 = threading.Event()
1248
1249        th1 = threading.Thread(target=thfunc1, args=(self,))
1250        th2 = threading.Thread(target=thfunc2, args=(self,))
1251
1252        th1.start()
1253        th2.start()
1254
1255        self.finish1.wait()
1256        self.finish2.wait()
1257
1258
1259class DecimalUsabilityTest(unittest.TestCase):
1260    '''Unit tests for Usability cases of Decimal.'''
1261
1262    def test_comparison_operators(self):
1263
1264        da = Decimal('23.42')
1265        db = Decimal('23.42')
1266        dc = Decimal('45')
1267
1268        #two Decimals
1269        self.assertGreater(dc, da)
1270        self.assertGreaterEqual(dc, da)
1271        self.assertLess(da, dc)
1272        self.assertLessEqual(da, dc)
1273        self.assertEqual(da, db)
1274        self.assertNotEqual(da, dc)
1275        self.assertLessEqual(da, db)
1276        self.assertGreaterEqual(da, db)
1277        self.assertEqual(cmp(dc,da), 1)
1278        self.assertEqual(cmp(da,dc), -1)
1279        self.assertEqual(cmp(da,db), 0)
1280
1281        #a Decimal and an int
1282        self.assertGreater(dc, 23)
1283        self.assertLess(23, dc)
1284        self.assertEqual(dc, 45)
1285        self.assertEqual(cmp(dc,23), 1)
1286        self.assertEqual(cmp(23,dc), -1)
1287        self.assertEqual(cmp(dc,45), 0)
1288
1289        #a Decimal and uncomparable
1290        self.assertNotEqual(da, 'ugly')
1291        self.assertNotEqual(da, 32.7)
1292        self.assertNotEqual(da, object())
1293        self.assertNotEqual(da, object)
1294
1295        # sortable
1296        a = map(Decimal, xrange(100))
1297        b =  a[:]
1298        random.shuffle(a)
1299        a.sort()
1300        self.assertEqual(a, b)
1301
1302        # with None
1303        with check_py3k_warnings():
1304            self.assertFalse(Decimal(1) < None)
1305            self.assertTrue(Decimal(1) > None)
1306
1307    def test_decimal_float_comparison(self):
1308        da = Decimal('0.25')
1309        db = Decimal('3.0')
1310        self.assertLess(da, 3.0)
1311        self.assertLessEqual(da, 3.0)
1312        self.assertGreater(db, 0.25)
1313        self.assertGreaterEqual(db, 0.25)
1314        self.assertNotEqual(da, 1.5)
1315        self.assertEqual(da, 0.25)
1316        self.assertGreater(3.0, da)
1317        self.assertGreaterEqual(3.0, da)
1318        self.assertLess(0.25, db)
1319        self.assertLessEqual(0.25, db)
1320        self.assertNotEqual(0.25, db)
1321        self.assertEqual(3.0, db)
1322        self.assertNotEqual(0.1, Decimal('0.1'))
1323
1324    def test_copy_and_deepcopy_methods(self):
1325        d = Decimal('43.24')
1326        c = copy.copy(d)
1327        self.assertEqual(id(c), id(d))
1328        dc = copy.deepcopy(d)
1329        self.assertEqual(id(dc), id(d))
1330
1331    def test_hash_method(self):
1332        #just that it's hashable
1333        hash(Decimal(23))
1334        hash(Decimal('Infinity'))
1335        hash(Decimal('-Infinity'))
1336        hash(Decimal('nan123'))
1337        hash(Decimal('-NaN'))
1338
1339        test_values = [Decimal(sign*(2**m + n))
1340                       for m in [0, 14, 15, 16, 17, 30, 31,
1341                                 32, 33, 62, 63, 64, 65, 66]
1342                       for n in range(-10, 10)
1343                       for sign in [-1, 1]]
1344        test_values.extend([
1345                Decimal("-0"), # zeros
1346                Decimal("0.00"),
1347                Decimal("-0.000"),
1348                Decimal("0E10"),
1349                Decimal("-0E12"),
1350                Decimal("10.0"), # negative exponent
1351                Decimal("-23.00000"),
1352                Decimal("1230E100"), # positive exponent
1353                Decimal("-4.5678E50"),
1354                # a value for which hash(n) != hash(n % (2**64-1))
1355                # in Python pre-2.6
1356                Decimal(2**64 + 2**32 - 1),
1357                # selection of values which fail with the old (before
1358                # version 2.6) long.__hash__
1359                Decimal("1.634E100"),
1360                Decimal("90.697E100"),
1361                Decimal("188.83E100"),
1362                Decimal("1652.9E100"),
1363                Decimal("56531E100"),
1364                ])
1365
1366        # check that hash(d) == hash(int(d)) for integral values
1367        for value in test_values:
1368            self.assertEqual(hash(value), hash(int(value)))
1369
1370        #the same hash that to an int
1371        self.assertEqual(hash(Decimal(23)), hash(23))
1372        self.assertRaises(TypeError, hash, Decimal('sNaN'))
1373        self.assertTrue(hash(Decimal('Inf')))
1374        self.assertTrue(hash(Decimal('-Inf')))
1375
1376        # check that the hashes of a Decimal float match when they
1377        # represent exactly the same values
1378        test_strings = ['inf', '-Inf', '0.0', '-.0e1',
1379                        '34.0', '2.5', '112390.625', '-0.515625']
1380        for s in test_strings:
1381            f = float(s)
1382            d = Decimal(s)
1383            self.assertEqual(hash(f), hash(d))
1384
1385        # check that the value of the hash doesn't depend on the
1386        # current context (issue #1757)
1387        c = getcontext()
1388        old_precision = c.prec
1389        x = Decimal("123456789.1")
1390
1391        c.prec = 6
1392        h1 = hash(x)
1393        c.prec = 10
1394        h2 = hash(x)
1395        c.prec = 16
1396        h3 = hash(x)
1397
1398        self.assertEqual(h1, h2)
1399        self.assertEqual(h1, h3)
1400        c.prec = old_precision
1401
1402    def test_min_and_max_methods(self):
1403
1404        d1 = Decimal('15.32')
1405        d2 = Decimal('28.5')
1406        l1 = 15
1407        l2 = 28
1408
1409        #between Decimals
1410        self.assertIs(min(d1,d2), d1)
1411        self.assertIs(min(d2,d1), d1)
1412        self.assertIs(max(d1,d2), d2)
1413        self.assertIs(max(d2,d1), d2)
1414
1415        #between Decimal and long
1416        self.assertIs(min(d1,l2), d1)
1417        self.assertIs(min(l2,d1), d1)
1418        self.assertIs(max(l1,d2), d2)
1419        self.assertIs(max(d2,l1), d2)
1420
1421    def test_as_nonzero(self):
1422        #as false
1423        self.assertFalse(Decimal(0))
1424        #as true
1425        self.assertTrue(Decimal('0.372'))
1426
1427    def test_tostring_methods(self):
1428        #Test str and repr methods.
1429
1430        d = Decimal('15.32')
1431        self.assertEqual(str(d), '15.32')               # str
1432        self.assertEqual(repr(d), "Decimal('15.32')")   # repr
1433
1434        # result type of string methods should be str, not unicode
1435        unicode_inputs = [u'123.4', u'0.5E2', u'Infinity', u'sNaN',
1436                          u'-0.0E100', u'-NaN001', u'-Inf']
1437
1438        for u in unicode_inputs:
1439            d = Decimal(u)
1440            self.assertEqual(type(str(d)), str)
1441            self.assertEqual(type(repr(d)), str)
1442            self.assertEqual(type(d.to_eng_string()), str)
1443
1444    def test_tonum_methods(self):
1445        #Test float, int and long methods.
1446
1447        d1 = Decimal('66')
1448        d2 = Decimal('15.32')
1449
1450        #int
1451        self.assertEqual(int(d1), 66)
1452        self.assertEqual(int(d2), 15)
1453
1454        #long
1455        self.assertEqual(long(d1), 66)
1456        self.assertEqual(long(d2), 15)
1457
1458        #float
1459        self.assertEqual(float(d1), 66)
1460        self.assertEqual(float(d2), 15.32)
1461
1462    def test_nan_to_float(self):
1463        # Test conversions of decimal NANs to float.
1464        # See http://bugs.python.org/issue15544
1465        for s in ('nan', 'nan1234', '-nan', '-nan2468'):
1466            f = float(Decimal(s))
1467            self.assertTrue(math.isnan(f))
1468
1469    def test_snan_to_float(self):
1470        for s in ('snan', '-snan', 'snan1357', '-snan1234'):
1471            d = Decimal(s)
1472            self.assertRaises(ValueError, float, d)
1473
1474    def test_eval_round_trip(self):
1475
1476        #with zero
1477        d = Decimal( (0, (0,), 0) )
1478        self.assertEqual(d, eval(repr(d)))
1479
1480        #int
1481        d = Decimal( (1, (4, 5), 0) )
1482        self.assertEqual(d, eval(repr(d)))
1483
1484        #float
1485        d = Decimal( (0, (4, 5, 3, 4), -2) )
1486        self.assertEqual(d, eval(repr(d)))
1487
1488        #weird
1489        d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
1490        self.assertEqual(d, eval(repr(d)))
1491
1492    def test_as_tuple(self):
1493
1494        #with zero
1495        d = Decimal(0)
1496        self.assertEqual(d.as_tuple(), (0, (0,), 0) )
1497
1498        #int
1499        d = Decimal(-45)
1500        self.assertEqual(d.as_tuple(), (1, (4, 5), 0) )
1501
1502        #complicated string
1503        d = Decimal("-4.34913534E-17")
1504        self.assertEqual(d.as_tuple(), (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
1505
1506        #inf
1507        d = Decimal("Infinity")
1508        self.assertEqual(d.as_tuple(), (0, (0,), 'F') )
1509
1510        #leading zeros in coefficient should be stripped
1511        d = Decimal( (0, (0, 0, 4, 0, 5, 3, 4), -2) )
1512        self.assertEqual(d.as_tuple(), (0, (4, 0, 5, 3, 4), -2) )
1513        d = Decimal( (1, (0, 0, 0), 37) )
1514        self.assertEqual(d.as_tuple(), (1, (0,), 37))
1515        d = Decimal( (1, (), 37) )
1516        self.assertEqual(d.as_tuple(), (1, (0,), 37))
1517
1518        #leading zeros in NaN diagnostic info should be stripped
1519        d = Decimal( (0, (0, 0, 4, 0, 5, 3, 4), 'n') )
1520        self.assertEqual(d.as_tuple(), (0, (4, 0, 5, 3, 4), 'n') )
1521        d = Decimal( (1, (0, 0, 0), 'N') )
1522        self.assertEqual(d.as_tuple(), (1, (), 'N') )
1523        d = Decimal( (1, (), 'n') )
1524        self.assertEqual(d.as_tuple(), (1, (), 'n') )
1525
1526        #coefficient in infinity should be ignored
1527        d = Decimal( (0, (4, 5, 3, 4), 'F') )
1528        self.assertEqual(d.as_tuple(), (0, (0,), 'F'))
1529        d = Decimal( (1, (0, 2, 7, 1), 'F') )
1530        self.assertEqual(d.as_tuple(), (1, (0,), 'F'))
1531
1532    def test_immutability_operations(self):
1533        # Do operations and check that it didn't change change internal objects.
1534
1535        d1 = Decimal('-25e55')
1536        b1 = Decimal('-25e55')
1537        d2 = Decimal('33e+33')
1538        b2 = Decimal('33e+33')
1539
1540        def checkSameDec(operation, useOther=False):
1541            if useOther:
1542                eval("d1." + operation + "(d2)")
1543                self.assertEqual(d1._sign, b1._sign)
1544                self.assertEqual(d1._int, b1._int)
1545                self.assertEqual(d1._exp, b1._exp)
1546                self.assertEqual(d2._sign, b2._sign)
1547                self.assertEqual(d2._int, b2._int)
1548                self.assertEqual(d2._exp, b2._exp)
1549            else:
1550                eval("d1." + operation + "()")
1551                self.assertEqual(d1._sign, b1._sign)
1552                self.assertEqual(d1._int, b1._int)
1553                self.assertEqual(d1._exp, b1._exp)
1554
1555        Decimal(d1)
1556        self.assertEqual(d1._sign, b1._sign)
1557        self.assertEqual(d1._int, b1._int)
1558        self.assertEqual(d1._exp, b1._exp)
1559
1560        checkSameDec("__abs__")
1561        checkSameDec("__add__", True)
1562        checkSameDec("__div__", True)
1563        checkSameDec("__divmod__", True)
1564        checkSameDec("__eq__", True)
1565        checkSameDec("__ne__", True)
1566        checkSameDec("__le__", True)
1567        checkSameDec("__lt__", True)
1568        checkSameDec("__ge__", True)
1569        checkSameDec("__gt__", True)
1570        checkSameDec("__float__")
1571        checkSameDec("__floordiv__", True)
1572        checkSameDec("__hash__")
1573        checkSameDec("__int__")
1574        checkSameDec("__trunc__")
1575        checkSameDec("__long__")
1576        checkSameDec("__mod__", True)
1577        checkSameDec("__mul__", True)
1578        checkSameDec("__neg__")
1579        checkSameDec("__nonzero__")
1580        checkSameDec("__pos__")
1581        checkSameDec("__pow__", True)
1582        checkSameDec("__radd__", True)
1583        checkSameDec("__rdiv__", True)
1584        checkSameDec("__rdivmod__", True)
1585        checkSameDec("__repr__")
1586        checkSameDec("__rfloordiv__", True)
1587        checkSameDec("__rmod__", True)
1588        checkSameDec("__rmul__", True)
1589        checkSameDec("__rpow__", True)
1590        checkSameDec("__rsub__", True)
1591        checkSameDec("__str__")
1592        checkSameDec("__sub__", True)
1593        checkSameDec("__truediv__", True)
1594        checkSameDec("adjusted")
1595        checkSameDec("as_tuple")
1596        checkSameDec("compare", True)
1597        checkSameDec("max", True)
1598        checkSameDec("min", True)
1599        checkSameDec("normalize")
1600        checkSameDec("quantize", True)
1601        checkSameDec("remainder_near", True)
1602        checkSameDec("same_quantum", True)
1603        checkSameDec("sqrt")
1604        checkSameDec("to_eng_string")
1605        checkSameDec("to_integral")
1606
1607    def test_subclassing(self):
1608        # Different behaviours when subclassing Decimal
1609
1610        class MyDecimal(Decimal):
1611            pass
1612
1613        d1 = MyDecimal(1)
1614        d2 = MyDecimal(2)
1615        d = d1 + d2
1616        self.assertIs(type(d), Decimal)
1617
1618        d = d1.max(d2)
1619        self.assertIs(type(d), Decimal)
1620
1621    def test_implicit_context(self):
1622        # Check results when context given implicitly.  (Issue 2478)
1623        c = getcontext()
1624        self.assertEqual(str(Decimal(0).sqrt()),
1625                         str(c.sqrt(Decimal(0))))
1626
1627    def test_conversions_from_int(self):
1628        # Check that methods taking a second Decimal argument will
1629        # always accept an integer in place of a Decimal.
1630        self.assertEqual(Decimal(4).compare(3),
1631                         Decimal(4).compare(Decimal(3)))
1632        self.assertEqual(Decimal(4).compare_signal(3),
1633                         Decimal(4).compare_signal(Decimal(3)))
1634        self.assertEqual(Decimal(4).compare_total(3),
1635                         Decimal(4).compare_total(Decimal(3)))
1636        self.assertEqual(Decimal(4).compare_total_mag(3),
1637                         Decimal(4).compare_total_mag(Decimal(3)))
1638        self.assertEqual(Decimal(10101).logical_and(1001),
1639                         Decimal(10101).logical_and(Decimal(1001)))
1640        self.assertEqual(Decimal(10101).logical_or(1001),
1641                         Decimal(10101).logical_or(Decimal(1001)))
1642        self.assertEqual(Decimal(10101).logical_xor(1001),
1643                         Decimal(10101).logical_xor(Decimal(1001)))
1644        self.assertEqual(Decimal(567).max(123),
1645                         Decimal(567).max(Decimal(123)))
1646        self.assertEqual(Decimal(567).max_mag(123),
1647                         Decimal(567).max_mag(Decimal(123)))
1648        self.assertEqual(Decimal(567).min(123),
1649                         Decimal(567).min(Decimal(123)))
1650        self.assertEqual(Decimal(567).min_mag(123),
1651                         Decimal(567).min_mag(Decimal(123)))
1652        self.assertEqual(Decimal(567).next_toward(123),
1653                         Decimal(567).next_toward(Decimal(123)))
1654        self.assertEqual(Decimal(1234).quantize(100),
1655                         Decimal(1234).quantize(Decimal(100)))
1656        self.assertEqual(Decimal(768).remainder_near(1234),
1657                         Decimal(768).remainder_near(Decimal(1234)))
1658        self.assertEqual(Decimal(123).rotate(1),
1659                         Decimal(123).rotate(Decimal(1)))
1660        self.assertEqual(Decimal(1234).same_quantum(1000),
1661                         Decimal(1234).same_quantum(Decimal(1000)))
1662        self.assertEqual(Decimal('9.123').scaleb(-100),
1663                         Decimal('9.123').scaleb(Decimal(-100)))
1664        self.assertEqual(Decimal(456).shift(-1),
1665                         Decimal(456).shift(Decimal(-1)))
1666
1667        self.assertEqual(Decimal(-12).fma(Decimal(45), 67),
1668                         Decimal(-12).fma(Decimal(45), Decimal(67)))
1669        self.assertEqual(Decimal(-12).fma(45, 67),
1670                         Decimal(-12).fma(Decimal(45), Decimal(67)))
1671        self.assertEqual(Decimal(-12).fma(45, Decimal(67)),
1672                         Decimal(-12).fma(Decimal(45), Decimal(67)))
1673
1674
1675class DecimalPythonAPItests(unittest.TestCase):
1676
1677    def test_abc(self):
1678        self.assertTrue(issubclass(Decimal, numbers.Number))
1679        self.assertFalse(issubclass(Decimal, numbers.Real))
1680        self.assertIsInstance(Decimal(0), numbers.Number)
1681        self.assertNotIsInstance(Decimal(0), numbers.Real)
1682
1683    def test_pickle(self):
1684        d = Decimal('-3.141590000')
1685        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1686            p = pickle.dumps(d, proto)
1687            e = pickle.loads(p)
1688            self.assertEqual(d, e)
1689
1690    def test_int(self):
1691        for x in range(-250, 250):
1692            s = '%0.2f' % (x / 100.0)
1693            # should work the same as for floats
1694            self.assertEqual(int(Decimal(s)), int(float(s)))
1695            # should work the same as to_integral in the ROUND_DOWN mode
1696            d = Decimal(s)
1697            r = d.to_integral(ROUND_DOWN)
1698            self.assertEqual(Decimal(int(d)), r)
1699
1700        self.assertRaises(ValueError, int, Decimal('-nan'))
1701        self.assertRaises(ValueError, int, Decimal('snan'))
1702        self.assertRaises(OverflowError, int, Decimal('inf'))
1703        self.assertRaises(OverflowError, int, Decimal('-inf'))
1704
1705        self.assertRaises(ValueError, long, Decimal('-nan'))
1706        self.assertRaises(ValueError, long, Decimal('snan'))
1707        self.assertRaises(OverflowError, long, Decimal('inf'))
1708        self.assertRaises(OverflowError, long, Decimal('-inf'))
1709
1710    def test_trunc(self):
1711        for x in range(-250, 250):
1712            s = '%0.2f' % (x / 100.0)
1713            # should work the same as for floats
1714            self.assertEqual(int(Decimal(s)), int(float(s)))
1715            # should work the same as to_integral in the ROUND_DOWN mode
1716            d = Decimal(s)
1717            r = d.to_integral(ROUND_DOWN)
1718            self.assertEqual(Decimal(math.trunc(d)), r)
1719
1720    def test_from_float(self):
1721
1722        class  MyDecimal(Decimal):
1723            pass
1724
1725        r = MyDecimal.from_float(0.1)
1726        self.assertEqual(type(r), MyDecimal)
1727        self.assertEqual(str(r),
1728                '0.1000000000000000055511151231257827021181583404541015625')
1729        bigint = 12345678901234567890123456789
1730        self.assertEqual(MyDecimal.from_float(bigint), MyDecimal(bigint))
1731        self.assertTrue(MyDecimal.from_float(float('nan')).is_qnan())
1732        self.assertTrue(MyDecimal.from_float(float('inf')).is_infinite())
1733        self.assertTrue(MyDecimal.from_float(float('-inf')).is_infinite())
1734        self.assertEqual(str(MyDecimal.from_float(float('nan'))),
1735                         str(Decimal('NaN')))
1736        self.assertEqual(str(MyDecimal.from_float(float('inf'))),
1737                         str(Decimal('Infinity')))
1738        self.assertEqual(str(MyDecimal.from_float(float('-inf'))),
1739                         str(Decimal('-Infinity')))
1740        self.assertRaises(TypeError, MyDecimal.from_float, 'abc')
1741        for i in range(200):
1742            x = random.expovariate(0.01) * (random.random() * 2.0 - 1.0)
1743            self.assertEqual(x, float(MyDecimal.from_float(x))) # roundtrip
1744
1745    def test_create_decimal_from_float(self):
1746        context = Context(prec=5, rounding=ROUND_DOWN)
1747        self.assertEqual(
1748            context.create_decimal_from_float(math.pi),
1749            Decimal('3.1415')
1750        )
1751        context = Context(prec=5, rounding=ROUND_UP)
1752        self.assertEqual(
1753            context.create_decimal_from_float(math.pi),
1754            Decimal('3.1416')
1755        )
1756        context = Context(prec=5, traps=[Inexact])
1757        self.assertRaises(
1758            Inexact,
1759            context.create_decimal_from_float,
1760            math.pi
1761        )
1762        self.assertEqual(repr(context.create_decimal_from_float(-0.0)),
1763                         "Decimal('-0')")
1764        self.assertEqual(repr(context.create_decimal_from_float(1.0)),
1765                         "Decimal('1')")
1766        self.assertEqual(repr(context.create_decimal_from_float(10)),
1767                         "Decimal('10')")
1768
1769class ContextAPItests(unittest.TestCase):
1770
1771    def test_pickle(self):
1772        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1773            c = Context()
1774            e = pickle.loads(pickle.dumps(c, proto))
1775            for k in vars(c):
1776                v1 = vars(c)[k]
1777                v2 = vars(e)[k]
1778                self.assertEqual(v1, v2)
1779
1780    def test_equality_with_other_types(self):
1781        self.assertIn(Decimal(10), ['a', 1.0, Decimal(10), (1,2), {}])
1782        self.assertNotIn(Decimal(10), ['a', 1.0, (1,2), {}])
1783
1784    def test_copy(self):
1785        # All copies should be deep
1786        c = Context()
1787        d = c.copy()
1788        self.assertNotEqual(id(c), id(d))
1789        self.assertNotEqual(id(c.flags), id(d.flags))
1790        self.assertNotEqual(id(c.traps), id(d.traps))
1791
1792    def test_abs(self):
1793        c = Context()
1794        d = c.abs(Decimal(-1))
1795        self.assertEqual(c.abs(-1), d)
1796        self.assertRaises(TypeError, c.abs, '-1')
1797
1798    def test_add(self):
1799        c = Context()
1800        d = c.add(Decimal(1), Decimal(1))
1801        self.assertEqual(c.add(1, 1), d)
1802        self.assertEqual(c.add(Decimal(1), 1), d)
1803        self.assertEqual(c.add(1, Decimal(1)), d)
1804        self.assertRaises(TypeError, c.add, '1', 1)
1805        self.assertRaises(TypeError, c.add, 1, '1')
1806
1807    def test_compare(self):
1808        c = Context()
1809        d = c.compare(Decimal(1), Decimal(1))
1810        self.assertEqual(c.compare(1, 1), d)
1811        self.assertEqual(c.compare(Decimal(1), 1), d)
1812        self.assertEqual(c.compare(1, Decimal(1)), d)
1813        self.assertRaises(TypeError, c.compare, '1', 1)
1814        self.assertRaises(TypeError, c.compare, 1, '1')
1815
1816    def test_compare_signal(self):
1817        c = Context()
1818        d = c.compare_signal(Decimal(1), Decimal(1))
1819        self.assertEqual(c.compare_signal(1, 1), d)
1820        self.assertEqual(c.compare_signal(Decimal(1), 1), d)
1821        self.assertEqual(c.compare_signal(1, Decimal(1)), d)
1822        self.assertRaises(TypeError, c.compare_signal, '1', 1)
1823        self.assertRaises(TypeError, c.compare_signal, 1, '1')
1824
1825    def test_compare_total(self):
1826        c = Context()
1827        d = c.compare_total(Decimal(1), Decimal(1))
1828        self.assertEqual(c.compare_total(1, 1), d)
1829        self.assertEqual(c.compare_total(Decimal(1), 1), d)
1830        self.assertEqual(c.compare_total(1, Decimal(1)), d)
1831        self.assertRaises(TypeError, c.compare_total, '1', 1)
1832        self.assertRaises(TypeError, c.compare_total, 1, '1')
1833
1834    def test_compare_total_mag(self):
1835        c = Context()
1836        d = c.compare_total_mag(Decimal(1), Decimal(1))
1837        self.assertEqual(c.compare_total_mag(1, 1), d)
1838        self.assertEqual(c.compare_total_mag(Decimal(1), 1), d)
1839        self.assertEqual(c.compare_total_mag(1, Decimal(1)), d)
1840        self.assertRaises(TypeError, c.compare_total_mag, '1', 1)
1841        self.assertRaises(TypeError, c.compare_total_mag, 1, '1')
1842
1843    def test_copy_abs(self):
1844        c = Context()
1845        d = c.copy_abs(Decimal(-1))
1846        self.assertEqual(c.copy_abs(-1), d)
1847        self.assertRaises(TypeError, c.copy_abs, '-1')
1848
1849    def test_copy_decimal(self):
1850        c = Context()
1851        d = c.copy_decimal(Decimal(-1))
1852        self.assertEqual(c.copy_decimal(-1), d)
1853        self.assertRaises(TypeError, c.copy_decimal, '-1')
1854
1855    def test_copy_negate(self):
1856        c = Context()
1857        d = c.copy_negate(Decimal(-1))
1858        self.assertEqual(c.copy_negate(-1), d)
1859        self.assertRaises(TypeError, c.copy_negate, '-1')
1860
1861    def test_copy_sign(self):
1862        c = Context()
1863        d = c.copy_sign(Decimal(1), Decimal(-2))
1864        self.assertEqual(c.copy_sign(1, -2), d)
1865        self.assertEqual(c.copy_sign(Decimal(1), -2), d)
1866        self.assertEqual(c.copy_sign(1, Decimal(-2)), d)
1867        self.assertRaises(TypeError, c.copy_sign, '1', -2)
1868        self.assertRaises(TypeError, c.copy_sign, 1, '-2')
1869
1870    def test_divide(self):
1871        c = Context()
1872        d = c.divide(Decimal(1), Decimal(2))
1873        self.assertEqual(c.divide(1, 2), d)
1874        self.assertEqual(c.divide(Decimal(1), 2), d)
1875        self.assertEqual(c.divide(1, Decimal(2)), d)
1876        self.assertRaises(TypeError, c.divide, '1', 2)
1877        self.assertRaises(TypeError, c.divide, 1, '2')
1878
1879    def test_divide_int(self):
1880        c = Context()
1881        d = c.divide_int(Decimal(1), Decimal(2))
1882        self.assertEqual(c.divide_int(1, 2), d)
1883        self.assertEqual(c.divide_int(Decimal(1), 2), d)
1884        self.assertEqual(c.divide_int(1, Decimal(2)), d)
1885        self.assertRaises(TypeError, c.divide_int, '1', 2)
1886        self.assertRaises(TypeError, c.divide_int, 1, '2')
1887
1888    def test_divmod(self):
1889        c = Context()
1890        d = c.divmod(Decimal(1), Decimal(2))
1891        self.assertEqual(c.divmod(1, 2), d)
1892        self.assertEqual(c.divmod(Decimal(1), 2), d)
1893        self.assertEqual(c.divmod(1, Decimal(2)), d)
1894        self.assertRaises(TypeError, c.divmod, '1', 2)
1895        self.assertRaises(TypeError, c.divmod, 1, '2')
1896
1897    def test_exp(self):
1898        c = Context()
1899        d = c.exp(Decimal(10))
1900        self.assertEqual(c.exp(10), d)
1901        self.assertRaises(TypeError, c.exp, '10')
1902
1903    def test_fma(self):
1904        c = Context()
1905        d = c.fma(Decimal(2), Decimal(3), Decimal(4))
1906        self.assertEqual(c.fma(2, 3, 4), d)
1907        self.assertEqual(c.fma(Decimal(2), 3, 4), d)
1908        self.assertEqual(c.fma(2, Decimal(3), 4), d)
1909        self.assertEqual(c.fma(2, 3, Decimal(4)), d)
1910        self.assertEqual(c.fma(Decimal(2), Decimal(3), 4), d)
1911        self.assertRaises(TypeError, c.fma, '2', 3, 4)
1912        self.assertRaises(TypeError, c.fma, 2, '3', 4)
1913        self.assertRaises(TypeError, c.fma, 2, 3, '4')
1914
1915    def test_is_finite(self):
1916        c = Context()
1917        d = c.is_finite(Decimal(10))
1918        self.assertEqual(c.is_finite(10), d)
1919        self.assertRaises(TypeError, c.is_finite, '10')
1920
1921    def test_is_infinite(self):
1922        c = Context()
1923        d = c.is_infinite(Decimal(10))
1924        self.assertEqual(c.is_infinite(10), d)
1925        self.assertRaises(TypeError, c.is_infinite, '10')
1926
1927    def test_is_nan(self):
1928        c = Context()
1929        d = c.is_nan(Decimal(10))
1930        self.assertEqual(c.is_nan(10), d)
1931        self.assertRaises(TypeError, c.is_nan, '10')
1932
1933    def test_is_normal(self):
1934        c = Context()
1935        d = c.is_normal(Decimal(10))
1936        self.assertEqual(c.is_normal(10), d)
1937        self.assertRaises(TypeError, c.is_normal, '10')
1938
1939    def test_is_qnan(self):
1940        c = Context()
1941        d = c.is_qnan(Decimal(10))
1942        self.assertEqual(c.is_qnan(10), d)
1943        self.assertRaises(TypeError, c.is_qnan, '10')
1944
1945    def test_is_signed(self):
1946        c = Context()
1947        d = c.is_signed(Decimal(10))
1948        self.assertEqual(c.is_signed(10), d)
1949        self.assertRaises(TypeError, c.is_signed, '10')
1950
1951    def test_is_snan(self):
1952        c = Context()
1953        d = c.is_snan(Decimal(10))
1954        self.assertEqual(c.is_snan(10), d)
1955        self.assertRaises(TypeError, c.is_snan, '10')
1956
1957    def test_is_subnormal(self):
1958        c = Context()
1959        d = c.is_subnormal(Decimal(10))
1960        self.assertEqual(c.is_subnormal(10), d)
1961        self.assertRaises(TypeError, c.is_subnormal, '10')
1962
1963    def test_is_zero(self):
1964        c = Context()
1965        d = c.is_zero(Decimal(10))
1966        self.assertEqual(c.is_zero(10), d)
1967        self.assertRaises(TypeError, c.is_zero, '10')
1968
1969    def test_ln(self):
1970        c = Context()
1971        d = c.ln(Decimal(10))
1972        self.assertEqual(c.ln(10), d)
1973        self.assertRaises(TypeError, c.ln, '10')
1974
1975    def test_log10(self):
1976        c = Context()
1977        d = c.log10(Decimal(10))
1978        self.assertEqual(c.log10(10), d)
1979        self.assertRaises(TypeError, c.log10, '10')
1980
1981    def test_logb(self):
1982        c = Context()
1983        d = c.logb(Decimal(10))
1984        self.assertEqual(c.logb(10), d)
1985        self.assertRaises(TypeError, c.logb, '10')
1986
1987    def test_logical_and(self):
1988        c = Context()
1989        d = c.logical_and(Decimal(1), Decimal(1))
1990        self.assertEqual(c.logical_and(1, 1), d)
1991        self.assertEqual(c.logical_and(Decimal(1), 1), d)
1992        self.assertEqual(c.logical_and(1, Decimal(1)), d)
1993        self.assertRaises(TypeError, c.logical_and, '1', 1)
1994        self.assertRaises(TypeError, c.logical_and, 1, '1')
1995
1996    def test_logical_invert(self):
1997        c = Context()
1998        d = c.logical_invert(Decimal(1000))
1999        self.assertEqual(c.logical_invert(1000), d)
2000        self.assertRaises(TypeError, c.logical_invert, '1000')
2001
2002    def test_logical_or(self):
2003        c = Context()
2004        d = c.logical_or(Decimal(1), Decimal(1))
2005        self.assertEqual(c.logical_or(1, 1), d)
2006        self.assertEqual(c.logical_or(Decimal(1), 1), d)
2007        self.assertEqual(c.logical_or(1, Decimal(1)), d)
2008        self.assertRaises(TypeError, c.logical_or, '1', 1)
2009        self.assertRaises(TypeError, c.logical_or, 1, '1')
2010
2011    def test_logical_xor(self):
2012        c = Context()
2013        d = c.logical_xor(Decimal(1), Decimal(1))
2014        self.assertEqual(c.logical_xor(1, 1), d)
2015        self.assertEqual(c.logical_xor(Decimal(1), 1), d)
2016        self.assertEqual(c.logical_xor(1, Decimal(1)), d)
2017        self.assertRaises(TypeError, c.logical_xor, '1', 1)
2018        self.assertRaises(TypeError, c.logical_xor, 1, '1')
2019
2020    def test_max(self):
2021        c = Context()
2022        d = c.max(Decimal(1), Decimal(2))
2023        self.assertEqual(c.max(1, 2), d)
2024        self.assertEqual(c.max(Decimal(1), 2), d)
2025        self.assertEqual(c.max(1, Decimal(2)), d)
2026        self.assertRaises(TypeError, c.max, '1', 2)
2027        self.assertRaises(TypeError, c.max, 1, '2')
2028
2029    def test_max_mag(self):
2030        c = Context()
2031        d = c.max_mag(Decimal(1), Decimal(2))
2032        self.assertEqual(c.max_mag(1, 2), d)
2033        self.assertEqual(c.max_mag(Decimal(1), 2), d)
2034        self.assertEqual(c.max_mag(1, Decimal(2)), d)
2035        self.assertRaises(TypeError, c.max_mag, '1', 2)
2036        self.assertRaises(TypeError, c.max_mag, 1, '2')
2037
2038    def test_min(self):
2039        c = Context()
2040        d = c.min(Decimal(1), Decimal(2))
2041        self.assertEqual(c.min(1, 2), d)
2042        self.assertEqual(c.min(Decimal(1), 2), d)
2043        self.assertEqual(c.min(1, Decimal(2)), d)
2044        self.assertRaises(TypeError, c.min, '1', 2)
2045        self.assertRaises(TypeError, c.min, 1, '2')
2046
2047    def test_min_mag(self):
2048        c = Context()
2049        d = c.min_mag(Decimal(1), Decimal(2))
2050        self.assertEqual(c.min_mag(1, 2), d)
2051        self.assertEqual(c.min_mag(Decimal(1), 2), d)
2052        self.assertEqual(c.min_mag(1, Decimal(2)), d)
2053        self.assertRaises(TypeError, c.min_mag, '1', 2)
2054        self.assertRaises(TypeError, c.min_mag, 1, '2')
2055
2056    def test_minus(self):
2057        c = Context()
2058        d = c.minus(Decimal(10))
2059        self.assertEqual(c.minus(10), d)
2060        self.assertRaises(TypeError, c.minus, '10')
2061
2062    def test_multiply(self):
2063        c = Context()
2064        d = c.multiply(Decimal(1), Decimal(2))
2065        self.assertEqual(c.multiply(1, 2), d)
2066        self.assertEqual(c.multiply(Decimal(1), 2), d)
2067        self.assertEqual(c.multiply(1, Decimal(2)), d)
2068        self.assertRaises(TypeError, c.multiply, '1', 2)
2069        self.assertRaises(TypeError, c.multiply, 1, '2')
2070
2071    def test_next_minus(self):
2072        c = Context()
2073        d = c.next_minus(Decimal(10))
2074        self.assertEqual(c.next_minus(10), d)
2075        self.assertRaises(TypeError, c.next_minus, '10')
2076
2077    def test_next_plus(self):
2078        c = Context()
2079        d = c.next_plus(Decimal(10))
2080        self.assertEqual(c.next_plus(10), d)
2081        self.assertRaises(TypeError, c.next_plus, '10')
2082
2083    def test_next_toward(self):
2084        c = Context()
2085        d = c.next_toward(Decimal(1), Decimal(2))
2086        self.assertEqual(c.next_toward(1, 2), d)
2087        self.assertEqual(c.next_toward(Decimal(1), 2), d)
2088        self.assertEqual(c.next_toward(1, Decimal(2)), d)
2089        self.assertRaises(TypeError, c.next_toward, '1', 2)
2090        self.assertRaises(TypeError, c.next_toward, 1, '2')
2091
2092    def test_normalize(self):
2093        c = Context()
2094        d = c.normalize(Decimal(10))
2095        self.assertEqual(c.normalize(10), d)
2096        self.assertRaises(TypeError, c.normalize, '10')
2097
2098    def test_number_class(self):
2099        c = Context()
2100        self.assertEqual(c.number_class(123), c.number_class(Decimal(123)))
2101        self.assertEqual(c.number_class(0), c.number_class(Decimal(0)))
2102        self.assertEqual(c.number_class(-45), c.number_class(Decimal(-45)))
2103
2104    def test_power(self):
2105        c = Context()
2106        d = c.power(Decimal(1), Decimal(4), Decimal(2))
2107        self.assertEqual(c.power(1, 4, 2), d)
2108        self.assertEqual(c.power(Decimal(1), 4, 2), d)
2109        self.assertEqual(c.power(1, Decimal(4), 2), d)
2110        self.assertEqual(c.power(1, 4, Decimal(2)), d)
2111        self.assertEqual(c.power(Decimal(1), Decimal(4), 2), d)
2112        self.assertRaises(TypeError, c.power, '1', 4, 2)
2113        self.assertRaises(TypeError, c.power, 1, '4', 2)
2114        self.assertRaises(TypeError, c.power, 1, 4, '2')
2115
2116    def test_plus(self):
2117        c = Context()
2118        d = c.plus(Decimal(10))
2119        self.assertEqual(c.plus(10), d)
2120        self.assertRaises(TypeError, c.plus, '10')
2121
2122    def test_quantize(self):
2123        c = Context()
2124        d = c.quantize(Decimal(1), Decimal(2))
2125        self.assertEqual(c.quantize(1, 2), d)
2126        self.assertEqual(c.quantize(Decimal(1), 2), d)
2127        self.assertEqual(c.quantize(1, Decimal(2)), d)
2128        self.assertRaises(TypeError, c.quantize, '1', 2)
2129        self.assertRaises(TypeError, c.quantize, 1, '2')
2130
2131    def test_remainder(self):
2132        c = Context()
2133        d = c.remainder(Decimal(1), Decimal(2))
2134        self.assertEqual(c.remainder(1, 2), d)
2135        self.assertEqual(c.remainder(Decimal(1), 2), d)
2136        self.assertEqual(c.remainder(1, Decimal(2)), d)
2137        self.assertRaises(TypeError, c.remainder, '1', 2)
2138        self.assertRaises(TypeError, c.remainder, 1, '2')
2139
2140    def test_remainder_near(self):
2141        c = Context()
2142        d = c.remainder_near(Decimal(1), Decimal(2))
2143        self.assertEqual(c.remainder_near(1, 2), d)
2144        self.assertEqual(c.remainder_near(Decimal(1), 2), d)
2145        self.assertEqual(c.remainder_near(1, Decimal(2)), d)
2146        self.assertRaises(TypeError, c.remainder_near, '1', 2)
2147        self.assertRaises(TypeError, c.remainder_near, 1, '2')
2148
2149    def test_rotate(self):
2150        c = Context()
2151        d = c.rotate(Decimal(1), Decimal(2))
2152        self.assertEqual(c.rotate(1, 2), d)
2153        self.assertEqual(c.rotate(Decimal(1), 2), d)
2154        self.assertEqual(c.rotate(1, Decimal(2)), d)
2155        self.assertRaises(TypeError, c.rotate, '1', 2)
2156        self.assertRaises(TypeError, c.rotate, 1, '2')
2157
2158    def test_sqrt(self):
2159        c = Context()
2160        d = c.sqrt(Decimal(10))
2161        self.assertEqual(c.sqrt(10), d)
2162        self.assertRaises(TypeError, c.sqrt, '10')
2163
2164    def test_same_quantum(self):
2165        c = Context()
2166        d = c.same_quantum(Decimal(1), Decimal(2))
2167        self.assertEqual(c.same_quantum(1, 2), d)
2168        self.assertEqual(c.same_quantum(Decimal(1), 2), d)
2169        self.assertEqual(c.same_quantum(1, Decimal(2)), d)
2170        self.assertRaises(TypeError, c.same_quantum, '1', 2)
2171        self.assertRaises(TypeError, c.same_quantum, 1, '2')
2172
2173    def test_scaleb(self):
2174        c = Context()
2175        d = c.scaleb(Decimal(1), Decimal(2))
2176        self.assertEqual(c.scaleb(1, 2), d)
2177        self.assertEqual(c.scaleb(Decimal(1), 2), d)
2178        self.assertEqual(c.scaleb(1, Decimal(2)), d)
2179        self.assertRaises(TypeError, c.scaleb, '1', 2)
2180        self.assertRaises(TypeError, c.scaleb, 1, '2')
2181
2182    def test_shift(self):
2183        c = Context()
2184        d = c.shift(Decimal(1), Decimal(2))
2185        self.assertEqual(c.shift(1, 2), d)
2186        self.assertEqual(c.shift(Decimal(1), 2), d)
2187        self.assertEqual(c.shift(1, Decimal(2)), d)
2188        self.assertRaises(TypeError, c.shift, '1', 2)
2189        self.assertRaises(TypeError, c.shift, 1, '2')
2190
2191    def test_subtract(self):
2192        c = Context()
2193        d = c.subtract(Decimal(1), Decimal(2))
2194        self.assertEqual(c.subtract(1, 2), d)
2195        self.assertEqual(c.subtract(Decimal(1), 2), d)
2196        self.assertEqual(c.subtract(1, Decimal(2)), d)
2197        self.assertRaises(TypeError, c.subtract, '1', 2)
2198        self.assertRaises(TypeError, c.subtract, 1, '2')
2199
2200    def test_to_eng_string(self):
2201        c = Context()
2202        d = c.to_eng_string(Decimal(10))
2203        self.assertEqual(c.to_eng_string(10), d)
2204        self.assertRaises(TypeError, c.to_eng_string, '10')
2205
2206    def test_to_sci_string(self):
2207        c = Context()
2208        d = c.to_sci_string(Decimal(10))
2209        self.assertEqual(c.to_sci_string(10), d)
2210        self.assertRaises(TypeError, c.to_sci_string, '10')
2211
2212    def test_to_integral_exact(self):
2213        c = Context()
2214        d = c.to_integral_exact(Decimal(10))
2215        self.assertEqual(c.to_integral_exact(10), d)
2216        self.assertRaises(TypeError, c.to_integral_exact, '10')
2217
2218    def test_to_integral_value(self):
2219        c = Context()
2220        d = c.to_integral_value(Decimal(10))
2221        self.assertEqual(c.to_integral_value(10), d)
2222        self.assertRaises(TypeError, c.to_integral_value, '10')
2223
2224class WithStatementTest(unittest.TestCase):
2225    # Can't do these as docstrings until Python 2.6
2226    # as doctest can't handle __future__ statements
2227
2228    def test_localcontext(self):
2229        # Use a copy of the current context in the block
2230        orig_ctx = getcontext()
2231        with localcontext() as enter_ctx:
2232            set_ctx = getcontext()
2233        final_ctx = getcontext()
2234        self.assertIs(orig_ctx, final_ctx, 'did not restore context correctly')
2235        self.assertIsNot(orig_ctx, set_ctx, 'did not copy the context')
2236        self.assertIs(set_ctx, enter_ctx, '__enter__ returned wrong context')
2237
2238    def test_localcontextarg(self):
2239        # Use a copy of the supplied context in the block
2240        orig_ctx = getcontext()
2241        new_ctx = Context(prec=42)
2242        with localcontext(new_ctx) as enter_ctx:
2243            set_ctx = getcontext()
2244        final_ctx = getcontext()
2245        self.assertIs(orig_ctx, final_ctx, 'did not restore context correctly')
2246        self.assertEqual(set_ctx.prec, new_ctx.prec, 'did not set correct context')
2247        self.assertIsNot(new_ctx, set_ctx, 'did not copy the context')
2248        self.assertIs(set_ctx, enter_ctx, '__enter__ returned wrong context')
2249
2250class ContextFlags(unittest.TestCase):
2251    def test_flags_irrelevant(self):
2252        # check that the result (numeric result + flags raised) of an
2253        # arithmetic operation doesn't depend on the current flags
2254
2255        context = Context(prec=9, Emin = -999999999, Emax = 999999999,
2256                    rounding=ROUND_HALF_EVEN, traps=[], flags=[])
2257
2258        # operations that raise various flags, in the form (function, arglist)
2259        operations = [
2260            (context._apply, [Decimal("100E-1000000009")]),
2261            (context.sqrt, [Decimal(2)]),
2262            (context.add, [Decimal("1.23456789"), Decimal("9.87654321")]),
2263            (context.multiply, [Decimal("1.23456789"), Decimal("9.87654321")]),
2264            (context.subtract, [Decimal("1.23456789"), Decimal("9.87654321")]),
2265            ]
2266
2267        # try various flags individually, then a whole lot at once
2268        flagsets = [[Inexact], [Rounded], [Underflow], [Clamped], [Subnormal],
2269                    [Inexact, Rounded, Underflow, Clamped, Subnormal]]
2270
2271        for fn, args in operations:
2272            # find answer and flags raised using a clean context
2273            context.clear_flags()
2274            ans = fn(*args)
2275            flags = [k for k, v in context.flags.items() if v]
2276
2277            for extra_flags in flagsets:
2278                # set flags, before calling operation
2279                context.clear_flags()
2280                for flag in extra_flags:
2281                    context._raise_error(flag)
2282                new_ans = fn(*args)
2283
2284                # flags that we expect to be set after the operation
2285                expected_flags = list(flags)
2286                for flag in extra_flags:
2287                    if flag not in expected_flags:
2288                        expected_flags.append(flag)
2289
2290                # flags we actually got
2291                new_flags = [k for k,v in context.flags.items() if v]
2292
2293                self.assertEqual(ans, new_ans,
2294                                 "operation produces different answers depending on flags set: " +
2295                                 "expected %s, got %s." % (ans, new_ans))
2296                self.assertItemsEqual(new_flags, expected_flags,
2297                                  "operation raises different flags depending on flags set: " +
2298                                  "expected %s, got %s" % (expected_flags, new_flags))
2299
2300def test_main(arith=None, verbose=None, todo_tests=None, debug=None):
2301    """ Execute the tests.
2302
2303    Runs all arithmetic tests if arith is True or if the "decimal" resource
2304    is enabled in regrtest.py
2305    """
2306
2307    init()
2308    global TEST_ALL, DEBUG
2309    TEST_ALL = arith if arith is not None else is_resource_enabled('decimal')
2310    DEBUG = debug
2311
2312    if todo_tests is None:
2313        test_classes = [
2314            DecimalExplicitConstructionTest,
2315            DecimalImplicitConstructionTest,
2316            DecimalArithmeticOperatorsTest,
2317            DecimalFormatTest,
2318            DecimalUseOfContextTest,
2319            DecimalUsabilityTest,
2320            DecimalPythonAPItests,
2321            ContextAPItests,
2322            DecimalTest,
2323            WithStatementTest,
2324            ContextFlags
2325        ]
2326    else:
2327        test_classes = [DecimalTest]
2328
2329    # Dynamically build custom test definition for each file in the test
2330    # directory and add the definitions to the DecimalTest class.  This
2331    # procedure insures that new files do not get skipped.
2332    for filename in os.listdir(directory):
2333        if '.decTest' not in filename or filename.startswith("."):
2334            continue
2335        head, tail = filename.split('.')
2336        if todo_tests is not None and head not in todo_tests:
2337            continue
2338        tester = lambda self, f=filename: self.eval_file(directory + f)
2339        setattr(DecimalTest, 'test_' + head, tester)
2340        del filename, head, tail, tester
2341
2342
2343    try:
2344        run_unittest(*test_classes)
2345        if todo_tests is None:
2346            import decimal as DecimalModule
2347            run_doctest(DecimalModule, verbose)
2348    finally:
2349        setcontext(ORIGINAL_CONTEXT)
2350
2351if __name__ == '__main__':
2352    import optparse
2353    p = optparse.OptionParser("test_decimal.py [--debug] [{--skip | test1 [test2 [...]]}]")
2354    p.add_option('--debug', '-d', action='store_true', help='shows the test number and context before each test')
2355    p.add_option('--skip',  '-s', action='store_true', help='skip over 90% of the arithmetic tests')
2356    (opt, args) = p.parse_args()
2357
2358    if opt.skip:
2359        test_main(arith=False, verbose=True)
2360    elif args:
2361        test_main(arith=True, verbose=True, todo_tests=args, debug=opt.debug)
2362    else:
2363        test_main(arith=True, verbose=True)
2364