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 warnings
31import pickle, copy
32import unittest
33import numbers
34import locale
35from test.test_support import run_unittest, run_doctest, is_resource_enabled
36from test.test_support import check_warnings, TestFailed
37import random
38import time
39import warnings
40import fractions
41try:
42    import threading
43except ImportError:
44    threading = None
45
46
47import cdecimal as C
48import decimal as P
49orig_sys_decimal = sys.modules['decimal']
50
51py_minor = sys.version_info[1]
52
53# Testing all failures of API functions for _decimal. First,
54# the number of API calls in a test case is determined. Then,
55# the testcase is run with all possible API failures, checking
56# that FailAPIException is properly raised.
57def assertRaises(expEx, func, *args, **kwargs):
58    """assertRaises has to reraise FailAPIException."""
59    try:
60        func(*args, **kwargs)
61    except Exception as e:
62       if e.__class__ is C.FailAPIException:
63           raise C.FailAPIException
64       if not e.__class__ is expEx:
65           raise e
66
67def withFailpoint(func):
68    """Wrap a function for testing all possible API failures."""
69    def iter_failpoint(testcase, *args):
70        # These tests will not work.
71        setattr(testcase, 'assertRaises', assertRaises)
72        # Determine number of API calls.
73        C.setapicalls(0)
74        C.setfailpoint(0)
75        func(testcase, *args)
76        n = C.getapicalls()
77        # Fail at each possible API call.
78        for i in range(1, n+1):
79            C.setapicalls(0)
80            C.setfailpoint(i)
81            try:
82                func(testcase, *args)
83            except C.FailAPIException:
84                continue
85            # Error: FailAPIException was not raised
86            raise TestFailed("FailAPIException not raised in: %s" % func)
87        C.setapicalls(0)
88        C.setfailpoint(0)
89    return iter_failpoint
90
91class ProtectFail(object):
92    """Protect code regions that modify global state (e.g. lines
93       that set or restore global context values). Otherwise it
94       would not be possible to rerun a test case several times."""
95    def __enter__(self):
96        if hasattr(C, 'setfailpoint'):
97            self.calls = C.getapicalls()
98            self.fpoint = C.getfailpoint()
99            C.setfailpoint(0)
100    def __exit__(self, *_):
101        if hasattr(C, 'setfailpoint'):
102            C.setfailpoint(self.fpoint)
103            if self.fpoint:
104                if self.calls < self.fpoint <= C.getapicalls():
105                    # Pretend that API calls in the protected block failed.
106                    raise C.FailAPIException
107
108def protectfail():
109    return ProtectFail()
110
111if hasattr(C, 'setfailpoint'):
112    # Functions that are iterated several times must use
113    # the same random sequence each time.
114    randseed = int(time.time())
115    # Implicit initialization of the module context must
116    # be tested first.
117    for i in range(1, 100):
118        C.setapicalls(0)
119        C.setfailpoint(i)
120        try:
121            C.getcontext()
122        except C.FailAPIException as e:
123            continue
124        C.setapicalls(0)
125        C.setfailpoint(0)
126
127# Useful Test Constant
128Signals = {
129  C: C.getcontext().flags.keys() if C else None,
130  P: P.getcontext().flags.keys()
131}
132# Signals ordered with respect to precedence: when an operation
133# produces multiple signals, signals occurring later in the list
134# should be handled before those occurring earlier in the list.
135OrderedSignals = {
136  C: [C.Clamped, C.Rounded, C.Inexact, C.Subnormal, C.Underflow,
137      C.Overflow, C.DivisionByZero, C.InvalidOperation] if C else None,
138  P: [P.Clamped, P.Rounded, P.Inexact, P.Subnormal, P.Underflow,
139      P.Overflow, P.DivisionByZero, P.InvalidOperation]
140}
141def assert_signals(cls, context, attr, expected):
142    d = getattr(context, attr)
143    cls.assertTrue(all(d[s] if s in expected else not d[s] for s in d))
144
145RoundingModes = {
146  C: (C.ROUND_UP, C.ROUND_DOWN, C.ROUND_CEILING, C.ROUND_FLOOR,
147      C.ROUND_HALF_UP, C.ROUND_HALF_DOWN, C.ROUND_HALF_EVEN,
148      C.ROUND_05UP) if C else None,
149  P: (P.ROUND_UP, P.ROUND_DOWN, P.ROUND_CEILING, P.ROUND_FLOOR,
150      P.ROUND_HALF_UP, P.ROUND_HALF_DOWN, P.ROUND_HALF_EVEN,
151      P.ROUND_05UP)
152}
153
154# Tests are built around these assumed context defaults.
155# test_main() restores the original context.
156ORIGINAL_CONTEXT = {
157  C: C.getcontext().copy() if C else None,
158  P: P.getcontext().copy()
159}
160def init(m):
161    if not m: return
162    DefaultTestContext = m.Context(
163       prec=9, rounding=m.ROUND_HALF_EVEN, traps=dict.fromkeys(Signals[m], 0)
164    )
165    m.setcontext(DefaultTestContext)
166
167TESTDATADIR = 'decimaltestdata'
168if __name__ == '__main__':
169    file = sys.argv[0]
170else:
171    file = __file__
172testdir = os.path.dirname(file) or os.curdir
173directory = testdir + os.sep + TESTDATADIR + os.sep
174
175skip_expected = not os.path.isdir(directory)
176
177# Make sure it actually raises errors when not expected and caught in flags
178# Slower, since it runs some things several times.
179EXTENDEDERRORTEST = False
180
181
182class IBMTestCases(unittest.TestCase):
183    """Class which tests the Decimal class against the IBM test cases."""
184
185    def setUp(self):
186        self.context = self.decimal.Context()
187        self.readcontext = self.decimal.Context()
188        self.ignore_list = ['#']
189
190        # List of individual .decTest test ids that correspond to tests that
191        # we're skipping for one reason or another.
192        self.skipped_test_ids = set([
193            # Skip implementation-specific scaleb tests.
194            'scbx164',
195            'scbx165',
196
197            # Skip large powers for _power_exact:
198            'extr1700',
199            'extr1701',
200            'extr1702',
201            'extr1703',
202
203            # For some operations (currently exp, ln, log10, power), the decNumber
204            # reference implementation imposes additional restrictions on the context
205            # and operands.  These restrictions are not part of the specification;
206            # however, the effect of these restrictions does show up in some of the
207            # testcases.  We skip testcases that violate these restrictions, since
208            # Decimal behaves differently from decNumber for these testcases so these
209            # testcases would otherwise fail.
210            'expx901',
211            'expx902',
212            'expx903',
213            'expx905',
214            'lnx901',
215            'lnx902',
216            'lnx903',
217            'lnx905',
218            'logx901',
219            'logx902',
220            'logx903',
221            'logx905',
222            'powx1183',
223            'powx1184',
224            'powx4001',
225            'powx4002',
226            'powx4003',
227            'powx4005',
228            'powx4008',
229            'powx4010',
230            'powx4012',
231            'powx4014',
232            # plus/minus special cases with ROUND_FLOOR (fixed in 3.3)
233            'minx1030',
234            'plux1031',
235            ])
236
237        if self.decimal == C:
238            # status has additional Subnormal, Underflow
239            self.skipped_test_ids.add('pwsx803')
240            self.skipped_test_ids.add('pwsx805')
241            # Correct rounding (skipped for decNumber, too)
242            self.skipped_test_ids.add('powx4302')
243            self.skipped_test_ids.add('powx4303')
244            self.skipped_test_ids.add('powx4342')
245            self.skipped_test_ids.add('powx4343')
246            # http://bugs.python.org/issue7049
247            self.skipped_test_ids.add('pwmx325')
248            self.skipped_test_ids.add('pwmx326')
249
250        # Map test directives to setter functions.
251        self.ChangeDict = {'precision' : self.change_precision,
252                           'rounding' : self.change_rounding_method,
253                           'maxexponent' : self.change_max_exponent,
254                           'minexponent' : self.change_min_exponent,
255                           'clamp' : self.change_clamp}
256
257        # Name adapter to be able to change the Decimal and Context
258        # interface without changing the test files from Cowlishaw.
259        self.NameAdapter = {'and':'logical_and',
260                            'apply':'_apply',
261                            'class':'number_class',
262                            'comparesig':'compare_signal',
263                            'comparetotal':'compare_total',
264                            'comparetotmag':'compare_total_mag',
265                            'copy':'copy_decimal',
266                            'copyabs':'copy_abs',
267                            'copynegate':'copy_negate',
268                            'copysign':'copy_sign',
269                            'divideint':'divide_int',
270                            'invert':'logical_invert',
271                            'iscanonical':'is_canonical',
272                            'isfinite':'is_finite',
273                            'isinfinite':'is_infinite',
274                            'isnan':'is_nan',
275                            'isnormal':'is_normal',
276                            'isqnan':'is_qnan',
277                            'issigned':'is_signed',
278                            'issnan':'is_snan',
279                            'issubnormal':'is_subnormal',
280                            'iszero':'is_zero',
281                            'maxmag':'max_mag',
282                            'minmag':'min_mag',
283                            'nextminus':'next_minus',
284                            'nextplus':'next_plus',
285                            'nexttoward':'next_toward',
286                            'or':'logical_or',
287                            'reduce':'normalize',
288                            'remaindernear':'remainder_near',
289                            'samequantum':'same_quantum',
290                            'squareroot':'sqrt',
291                            'toeng':'to_eng_string',
292                            'tointegral':'to_integral_value',
293                            'tointegralx':'to_integral_exact',
294                            'tosci':'to_sci_string',
295                            'xor':'logical_xor'}
296
297        # Map test-case names to roundings.
298        self.RoundingDict = {'ceiling' : self.decimal.ROUND_CEILING,
299                             'down' : self.decimal.ROUND_DOWN,
300                             'floor' : self.decimal.ROUND_FLOOR,
301                             'half_down' : self.decimal.ROUND_HALF_DOWN,
302                             'half_even' : self.decimal.ROUND_HALF_EVEN,
303                             'half_up' : self.decimal.ROUND_HALF_UP,
304                             'up' : self.decimal.ROUND_UP,
305                             '05up' : self.decimal.ROUND_05UP}
306
307        # Map the test cases' error names to the actual errors.
308        self.ErrorNames = {'clamped' : self.decimal.Clamped,
309                           'conversion_syntax' : self.decimal.InvalidOperation,
310                           'division_by_zero' : self.decimal.DivisionByZero,
311                           'division_impossible' : self.decimal.InvalidOperation,
312                           'division_undefined' : self.decimal.InvalidOperation,
313                           'inexact' : self.decimal.Inexact,
314                           'invalid_context' : self.decimal.InvalidOperation,
315                           'invalid_operation' : self.decimal.InvalidOperation,
316                           'overflow' : self.decimal.Overflow,
317                           'rounded' : self.decimal.Rounded,
318                           'subnormal' : self.decimal.Subnormal,
319                           'underflow' : self.decimal.Underflow}
320
321        # The following functions return True/False rather than a
322        # Decimal instance.
323        self.LogicalFunctions = ('is_canonical',
324                                 'is_finite',
325                                 'is_infinite',
326                                 'is_nan',
327                                 'is_normal',
328                                 'is_qnan',
329                                 'is_signed',
330                                 'is_snan',
331                                 'is_subnormal',
332                                 'is_zero',
333                                 'same_quantum')
334
335    def read_unlimited(self, v, context):
336        """Work around the limitations of the 32-bit _decimal version. The
337           guaranteed maximum values for prec, Emax etc. are 425000000,
338           but higher values usually work, except for rare corner cases.
339           In particular, all of the IBM tests pass with maximum values
340           of 1070000000."""
341        if self.decimal == C and self.decimal.MAX_EMAX == 425000000:
342            self.readcontext.unsafe_setprec(1070000000)
343            self.readcontext.unsafe_setemax(1070000000)
344            self.readcontext.unsafe_setemin(-1070000000)
345            return self.readcontext.create_decimal(v)
346        else:
347            return self.decimal.Decimal(v, context)
348
349    def eval_file(self, file):
350        global skip_expected
351        if skip_expected:
352            raise unittest.SkipTest
353            return
354        with open(file) as f:
355            for line in f:
356                line = line.replace('\r\n', '').replace('\n', '')
357                #print line
358                try:
359                    t = self.eval_line(line)
360                except self.decimal.DecimalException as exception:
361                    #Exception raised where there shouldn't have been one.
362                    self.fail('Exception "'+exception.__class__.__name__ + '" raised on line '+line)
363
364        return
365
366    def eval_line(self, s):
367        if s.find(' -> ') >= 0 and s[:2] != '--' and not s.startswith('  --'):
368            s = (s.split('->')[0] + '->' +
369                 s.split('->')[1].split('--')[0]).strip()
370        else:
371            s = s.split('--')[0].strip()
372
373        for ignore in self.ignore_list:
374            if s.find(ignore) >= 0:
375                #print s.split()[0], 'NotImplemented--', ignore
376                return
377        if not s:
378            return
379        elif ':' in s:
380            return self.eval_directive(s)
381        else:
382            return self.eval_equation(s)
383
384    def eval_directive(self, s):
385        funct, value = (x.strip().lower() for x in s.split(':'))
386        if funct == 'rounding':
387            value = self.RoundingDict[value]
388        else:
389            try:
390                value = int(value)
391            except ValueError:
392                pass
393
394        funct = self.ChangeDict.get(funct, (lambda *args: None))
395        funct(value)
396
397    def eval_equation(self, s):
398
399        if not TEST_ALL and not hasattr(C, 'setfailpoint') and \
400           random.random() < 0.90:
401            return
402
403        with protectfail():
404            self.context.clear_flags()
405
406        try:
407            Sides = s.split('->')
408            L = Sides[0].strip().split()
409            id = L[0]
410            if DEBUG:
411                print("Test ", id)
412            funct = L[1].lower()
413            valstemp = L[2:]
414            L = Sides[1].strip().split()
415            ans = L[0]
416            exceptions = L[1:]
417        except (TypeError, AttributeError, IndexError):
418            raise self.decimal.InvalidOperation
419        def FixQuotes(val):
420            val = val.replace("''", 'SingleQuote').replace('""', 'DoubleQuote')
421            val = val.replace("'", '').replace('"', '')
422            val = val.replace('SingleQuote', "'").replace('DoubleQuote', '"')
423            return val
424
425        if id in self.skipped_test_ids:
426            return
427
428        fname = self.NameAdapter.get(funct, funct)
429        if fname == 'rescale':
430            return
431        funct = getattr(self.context, fname)
432        vals = []
433        conglomerate = ''
434        quote = 0
435        theirexceptions = [self.ErrorNames[x.lower()] for x in exceptions]
436
437        for exception in Signals[self.decimal]:
438            self.context.traps[exception] = 1 #Catch these bugs...
439        for exception in theirexceptions:
440            self.context.traps[exception] = 0
441        for i, val in enumerate(valstemp):
442            if val.count("'") % 2 == 1:
443                quote = 1 - quote
444            if quote:
445                conglomerate = conglomerate + ' ' + val
446                continue
447            else:
448                val = conglomerate + val
449                conglomerate = ''
450            v = FixQuotes(val)
451            if fname in ('to_sci_string', 'to_eng_string'):
452                if EXTENDEDERRORTEST:
453                    for error in theirexceptions:
454                        self.context.traps[error] = 1
455                        try:
456                            funct(self.context.create_decimal(v))
457                        except error:
458                            pass
459                        except Signals[self.decimal] as e:
460                            self.fail("Raised %s in %s when %s disabled" % \
461                                      (e, s, error))
462                        else:
463                            self.fail("Did not raise %s in %s" % (error, s))
464                        self.context.traps[error] = 0
465                v = self.context.create_decimal(v)
466            else:
467                v = self.read_unlimited(v, self.context)
468            vals.append(v)
469
470        ans = FixQuotes(ans)
471
472        # three argument power/powmod (deprecated)
473        if self.decimal == C:
474            if fname == 'power' and len(vals) == 3:
475                # name is different
476                fname = 'powmod'
477                funct = getattr(self.context, fname)
478
479        if EXTENDEDERRORTEST and fname not in ('to_sci_string', 'to_eng_string'):
480            for error in theirexceptions:
481                self.context.traps[error] = 1
482                try:
483                    funct(*vals)
484                except error:
485                    pass
486                except Signals[self.decimal] as e:
487                    self.fail("Raised %s in %s when %s disabled" % \
488                              (e, s, error))
489                else:
490                    self.fail("Did not raise %s in %s" % (error, s))
491                self.context.traps[error] = 0
492
493            # as above, but add traps cumulatively, to check precedence
494            ordered_errors = [e for e in OrderedSignals[self.decimal] if e in theirexceptions]
495            for error in ordered_errors:
496                self.context.traps[error] = 1
497                try:
498                    funct(*vals)
499                except error:
500                    pass
501                except Signals[self.decimal] as e:
502                    self.fail("Raised %s in %s; expected %s" %
503                              (type(e), s, error))
504                else:
505                    self.fail("Did not raise %s in %s" % (error, s))
506            # reset traps
507            for error in ordered_errors:
508                self.context.traps[error] = 0
509
510
511        if DEBUG:
512            print("--", self.context)
513        try:
514            result = str(funct(*vals))
515            if fname in self.LogicalFunctions:
516                result = str(int(eval(result))) # 'True', 'False' -> '1', '0'
517        except Signals[self.decimal] as error:
518            self.fail("Raised %s in %s" % (error, s))
519        except Exception as e: #Catch any error long enough to state the test case.
520            # Errors are expected with failpoints.
521            if not hasattr(C, 'setfailpoint'):
522                print("ERROR:", s)
523            raise e.__class__
524
525        myexceptions = self.getexceptions()
526
527        myexceptions.sort(key=repr)
528        theirexceptions.sort(key=repr)
529
530        self.assertEqual(result, ans,
531                         'Incorrect answer for ' + s + ' -- got ' + result)
532
533        self.assertEqual(myexceptions, theirexceptions,
534              'Incorrect flags set in ' + s + ' -- got ' + str(myexceptions))
535        return
536
537    def getexceptions(self):
538        return [e for e in Signals[self.decimal] if self.context.flags[e]]
539
540    def change_precision(self, prec):
541        if self.decimal == C and self.decimal.MAX_PREC == 425000000:
542            self.context.unsafe_setprec(prec)
543        else:
544            self.context.prec = prec
545    def change_rounding_method(self, rounding):
546        self.context.rounding = rounding
547    def change_min_exponent(self, exp):
548        if self.decimal == C and self.decimal.MAX_PREC == 425000000:
549            self.context.unsafe_setemin(exp)
550        else:
551            self.context.Emin = exp
552    def change_max_exponent(self, exp):
553        if self.decimal == C and self.decimal.MAX_PREC == 425000000:
554            self.context.unsafe_setemax(exp)
555        else:
556            self.context.Emax = exp
557    def change_clamp(self, clamp):
558        self.context._clamp = clamp
559
560class CIBMTestCases(IBMTestCases):
561    decimal = C
562class PyIBMTestCases(IBMTestCases):
563    decimal = P
564
565# The following classes test the behaviour of Decimal according to PEP 327
566
567class ExplicitConstructionTest(unittest.TestCase):
568    '''Unit tests for Explicit Construction cases of Decimal.'''
569
570    def test_explicit_empty(self):
571        Decimal = self.decimal.Decimal
572        self.assertEqual(Decimal(), Decimal("0"))
573
574    def test_explicit_from_None(self):
575        Decimal = self.decimal.Decimal
576        self.assertRaises(TypeError, Decimal, None)
577
578    def test_explicit_from_int(self):
579        Decimal = self.decimal.Decimal
580
581        #positive
582        d = Decimal(45)
583        self.assertEqual(str(d), '45')
584
585        #very large positive
586        d = Decimal(500000123)
587        self.assertEqual(str(d), '500000123')
588
589        #negative
590        d = Decimal(-45)
591        self.assertEqual(str(d), '-45')
592
593        #zero
594        d = Decimal(0)
595        self.assertEqual(str(d), '0')
596        d = Decimal(0L)
597        self.assertEqual(str(d), '0')
598
599        # single word longs
600        for n in range(0, 32):
601            for sign in (-1, 1):
602                for x in range(-5, 5):
603                    i = sign * (2**n + x)
604                    d = Decimal(i)
605                    self.assertEqual(str(d), str(i))
606
607    def test_explicit_from_string(self):
608        Decimal = self.decimal.Decimal
609        InvalidOperation = self.decimal.InvalidOperation
610        localcontext = self.decimal.localcontext
611
612        #empty
613        self.assertEqual(str(Decimal('')), 'NaN')
614
615        #int
616        self.assertEqual(str(Decimal('45')), '45')
617
618        #float
619        self.assertEqual(str(Decimal('45.34')), '45.34')
620
621        #engineer notation
622        self.assertEqual(str(Decimal('45e2')), '4.5E+3')
623
624        #just not a number
625        self.assertEqual(str(Decimal('ugly')), 'NaN')
626
627        #leading and trailing whitespace permitted
628        self.assertEqual(str(Decimal('1.3E4 \n')), '1.3E+4')
629        self.assertEqual(str(Decimal('  -7.89')), '-7.89')
630        self.assertEqual(str(Decimal("  3.45679  ")), '3.45679')
631
632        #same for unicode
633        self.assertEqual(str(Decimal(u"  3.45679  ")), '3.45679')
634
635        #unicode strings should be permitted
636        self.assertEqual(str(Decimal(u'0E-017')), '0E-17')
637        self.assertEqual(str(Decimal(u'45')), '45')
638        self.assertEqual(str(Decimal(u'-Inf')), '-Infinity')
639        self.assertEqual(str(Decimal(u'NaN123')), 'NaN123')
640
641        with localcontext() as c:
642            c.traps[InvalidOperation] = True
643            # Invalid string
644            self.assertRaises(InvalidOperation, Decimal, "xyz")
645            self.assertRaises(InvalidOperation, Decimal, u"xyz")
646            # Two arguments max
647            self.assertRaises(TypeError, Decimal, "1234", "x", "y")
648
649    def test_explicit_from_tuples(self):
650        Decimal = self.decimal.Decimal
651
652        #zero
653        d = Decimal( (0, (0,), 0) )
654        self.assertEqual(str(d), '0')
655
656        #int
657        d = Decimal( (1, (4, 5), 0) )
658        self.assertEqual(str(d), '-45')
659
660        #float
661        d = Decimal( (0, (4, 5, 3, 4), -2) )
662        self.assertEqual(str(d), '45.34')
663
664        #weird
665        d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
666        self.assertEqual(str(d), '-4.34913534E-17')
667
668        #inf
669        d = Decimal( (0, (), "F") )
670        self.assertEqual(str(d), 'Infinity')
671
672        #wrong number of items
673        self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1)) )
674
675        #bad sign
676        self.assertRaises(ValueError, Decimal, (8, (4, 3, 4, 9, 1), 2) )
677        self.assertRaises(ValueError, Decimal, (0., (4, 3, 4, 9, 1), 2) )
678        self.assertRaises(ValueError, Decimal, (Decimal(1), (4, 3, 4, 9, 1), 2))
679
680        #bad exp
681        self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), 'wrong!') )
682        self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), 0.) )
683        self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), '1') )
684
685        #bad coefficients
686        self.assertRaises(ValueError, Decimal, (1, "xyz", 2) )
687        self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, None, 1), 2) )
688        self.assertRaises(ValueError, Decimal, (1, (4, -3, 4, 9, 1), 2) )
689        self.assertRaises(ValueError, Decimal, (1, (4, 10, 4, 9, 1), 2) )
690        self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 'a', 1), 2) )
691
692    def test_explicit_from_bool(self):
693        Decimal = self.decimal.Decimal
694
695        self.assertTrue(bool(Decimal(0)) is False)
696        self.assertTrue(bool(Decimal(1)) is True)
697        self.assertEqual(Decimal(False), Decimal(0))
698        self.assertEqual(Decimal(True), Decimal(1))
699
700    def test_explicit_from_Decimal(self):
701        Decimal = self.decimal.Decimal
702
703        #positive
704        d = Decimal(45)
705        e = Decimal(d)
706        self.assertEqual(str(e), '45')
707
708        #very large positive
709        d = Decimal(500000123)
710        e = Decimal(d)
711        self.assertEqual(str(e), '500000123')
712
713        #negative
714        d = Decimal(-45)
715        e = Decimal(d)
716        self.assertEqual(str(e), '-45')
717
718        #zero
719        d = Decimal(0)
720        e = Decimal(d)
721        self.assertEqual(str(e), '0')
722
723    def test_explicit_from_float(self):
724        if not float.__getformat__("double").startswith("IEEE"):
725            return
726        if hasattr(C, 'setfailpoint'):
727            random.seed(randseed)
728
729        Decimal = self.decimal.Decimal
730        localcontext = self.decimal.localcontext
731
732        if self.decimal == C:
733            FloatOperation = self.decimal.FloatOperation
734            if py_minor <= 6:
735                with localcontext() as c:
736                    # TypeError in 2.6
737                    c.clear_flags()
738                    self.assertRaises(TypeError, Decimal, 7.5)
739                    self.assertFalse(c.flags[FloatOperation])
740
741                    c.traps[FloatOperation] = True
742                    self.assertRaises(TypeError, Decimal, 7.5)
743                    self.assertFalse(c.flags[FloatOperation])
744                    return
745            else:
746                with localcontext() as c:
747                    c.clear_flags()
748                    self.assertEqual(Decimal(7.5), 7.5)
749                    self.assertTrue(c.flags[FloatOperation])
750
751                    c.traps[FloatOperation] = True
752                    self.assertRaises(FloatOperation, Decimal, 7.5)
753                    self.assertTrue(c.flags[FloatOperation])
754
755        r = Decimal.from_float(0.1)
756        self.assertEqual(type(r), Decimal)
757        self.assertEqual(str(r),
758                '0.1000000000000000055511151231257827021181583404541015625')
759        self.assertTrue(Decimal.from_float(float('nan')).is_qnan())
760        self.assertTrue(Decimal.from_float(float('inf')).is_infinite())
761        self.assertTrue(Decimal.from_float(float('-inf')).is_infinite())
762        self.assertEqual(str(Decimal.from_float(float('nan'))),
763                         str(Decimal('NaN')))
764        self.assertEqual(str(Decimal.from_float(float('inf'))),
765                         str(Decimal('Infinity')))
766        self.assertEqual(str(Decimal.from_float(float('-inf'))),
767                         str(Decimal('-Infinity')))
768        self.assertEqual(str(Decimal.from_float(float('-0.0'))),
769                         str(Decimal('-0')))
770        for i in range(200):
771            x = random.expovariate(0.01) * (random.random() * 2.0 - 1.0)
772            self.assertEqual(x, float(Decimal.from_float(x))) # roundtrip
773
774
775    def test_explicit_context_create_decimal(self):
776        Decimal = self.decimal.Decimal
777        InvalidOperation = self.decimal.InvalidOperation
778        Rounded = self.decimal.Rounded
779
780        nc = copy.copy(self.decimal.getcontext())
781        nc.prec = 3
782
783        # empty
784        d = Decimal()
785        self.assertEqual(str(d), '0')
786        d = nc.create_decimal()
787        self.assertEqual(str(d), '0')
788
789        # from None
790        self.assertRaises(TypeError, nc.create_decimal, None)
791
792        # from int
793        d = nc.create_decimal(456)
794        self.assertTrue(isinstance(d, Decimal))
795        self.assertEqual(nc.create_decimal(45678),
796                         nc.create_decimal('457E+2'))
797
798        # from string
799        d = Decimal('456789')
800        self.assertEqual(str(d), '456789')
801        d = nc.create_decimal('456789')
802        self.assertEqual(str(d), '4.57E+5')
803        # leading and trailing whitespace should result in a NaN;
804        # spaces are already checked in Cowlishaw's test-suite, so
805        # here we just check that a trailing newline results in a NaN
806        self.assertEqual(str(nc.create_decimal('3.14\n')), 'NaN')
807
808        # from tuples
809        d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
810        self.assertEqual(str(d), '-4.34913534E-17')
811        d = nc.create_decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
812        self.assertEqual(str(d), '-4.35E-17')
813
814        # from Decimal
815        prevdec = Decimal(500000123)
816        d = Decimal(prevdec)
817        self.assertEqual(str(d), '500000123')
818        d = nc.create_decimal(prevdec)
819        self.assertEqual(str(d), '5.00E+8')
820
821        # more integers
822        nc.prec = 28
823        nc.traps[InvalidOperation] = True
824
825        for v in [-2**63-1, -2**63, -2**31-1, -2**31, 0, 0L,
826                   2**31-1, 2**31, 2**63-1, 2**63]:
827            d = nc.create_decimal(v)
828            self.assertTrue(isinstance(d, Decimal))
829            self.assertEqual(int(d), v)
830
831        nc.prec = 3
832        nc.traps[Rounded] = True
833        self.assertRaises(Rounded, nc.create_decimal, 1234)
834        self.assertRaises(Rounded, nc.create_decimal, 1234L)
835
836        # from string
837        nc.prec = 28
838        self.assertEqual(str(nc.create_decimal('0E-017')), '0E-17')
839        self.assertEqual(str(nc.create_decimal('45')), '45')
840        self.assertEqual(str(nc.create_decimal('-Inf')), '-Infinity')
841        self.assertEqual(str(nc.create_decimal('NaN123')), 'NaN123')
842
843        # from unicode
844        self.assertEqual(str(nc.create_decimal(u'0E-017')), '0E-17')
845        self.assertEqual(str(nc.create_decimal(u'45')), '45')
846        self.assertEqual(str(nc.create_decimal(u'-Inf')), '-Infinity')
847        self.assertEqual(str(nc.create_decimal(u'NaN123')), 'NaN123')
848
849        # invalid arguments
850        self.assertRaises(InvalidOperation, nc.create_decimal, "xyz")
851        self.assertRaises(InvalidOperation, nc.create_decimal, u'xyz')
852        self.assertRaises(ValueError, nc.create_decimal, (1, "xyz", -25))
853        self.assertRaises(TypeError, nc.create_decimal, "1234", "5678")
854
855        # too many NaN payload digits
856        nc.prec = 3
857        self.assertRaises(InvalidOperation, nc.create_decimal, 'NaN12345')
858        self.assertRaises(InvalidOperation, nc.create_decimal,
859                          Decimal('NaN12345'))
860
861        nc.traps[InvalidOperation] = False
862        self.assertEqual(str(nc.create_decimal('NaN12345')), 'NaN')
863        self.assertTrue(nc.flags[InvalidOperation])
864
865        nc.flags[InvalidOperation] = False
866        self.assertEqual(str(nc.create_decimal(Decimal('NaN12345'))), 'NaN')
867        self.assertTrue(nc.flags[InvalidOperation])
868
869    def test_explicit_context_create_from_float(self):
870        if hasattr(C, 'setfailpoint'):
871            random.seed(randseed)
872
873        Decimal = self.decimal.Decimal
874        Context = self.decimal.Context
875
876        nc = Context()
877        if self.decimal == C:
878            FloatOperation = self.decimal.FloatOperation
879            if py_minor <= 6:
880                # TypeError in 2.6
881                nc.clear_flags()
882                self.assertRaises(TypeError, nc.create_decimal, 7.5)
883                self.assertFalse(nc.flags[FloatOperation])
884
885                nc.traps[FloatOperation] = True
886                self.assertRaises(TypeError, nc.create_decimal, 7.5)
887                self.assertFalse(nc.flags[FloatOperation])
888                nc.traps[FloatOperation] = False
889                return
890            else:
891                nc.clear_flags()
892                self.assertEqual(nc.create_decimal(7.5), 7.5)
893                self.assertTrue(nc.flags[FloatOperation])
894
895                nc.traps[FloatOperation] = True
896                self.assertRaises(FloatOperation, nc.create_decimal, 7.5)
897                self.assertTrue(nc.flags[FloatOperation])
898                nc.traps[FloatOperation] = False
899
900        r = nc.create_decimal_from_float(0.1)
901        self.assertEqual(type(r), Decimal)
902        self.assertEqual(str(r), '0.1000000000000000055511151231')
903        self.assertTrue(nc.create_decimal_from_float(float('nan')).is_qnan())
904        self.assertTrue(nc.create_decimal_from_float(float('inf')).is_infinite())
905        self.assertTrue(nc.create_decimal_from_float(float('-inf')).is_infinite())
906        self.assertEqual(str(nc.create_decimal_from_float(float('nan'))),
907                         str(nc.create_decimal('NaN')))
908        self.assertEqual(str(nc.create_decimal_from_float(float('inf'))),
909                         str(nc.create_decimal('Infinity')))
910        self.assertEqual(str(nc.create_decimal_from_float(float('-inf'))),
911                         str(nc.create_decimal('-Infinity')))
912        self.assertEqual(str(nc.create_decimal_from_float(float('-0.0'))),
913                         str(nc.create_decimal('-0')))
914        nc.prec = 100
915        for i in range(200):
916            x = random.expovariate(0.01) * (random.random() * 2.0 - 1.0)
917            self.assertEqual(x, float(nc.create_decimal_from_float(x))) # roundtrip
918
919    def test_unicode_digits(self):
920        Decimal = self.decimal.Decimal
921
922        test_values = {
923            u'\uff11': '1',
924            u'\u0660.\u0660\u0663\u0667\u0662e-\u0663' : '0.0000372',
925            u'-nan\u0c68\u0c6a\u0c66\u0c66' : '-NaN2400',
926            }
927        for input, expected in test_values.items():
928            self.assertEqual(str(Decimal(input)), expected)
929
930class CExplicitConstructionTest(ExplicitConstructionTest):
931    decimal = C
932class PyExplicitConstructionTest(ExplicitConstructionTest):
933    decimal = P
934
935class ImplicitConstructionTest(unittest.TestCase):
936    '''Unit tests for Implicit Construction cases of Decimal.'''
937
938    def test_implicit_from_None(self):
939        Decimal = self.decimal.Decimal
940        self.assertRaises(TypeError, eval, 'Decimal(5) + None', locals())
941
942    def test_implicit_from_int(self):
943        Decimal = self.decimal.Decimal
944
945        #normal
946        self.assertEqual(str(Decimal(5) + 45), '50')
947        #exceeding precision
948        self.assertEqual(Decimal(5) + 123456789000, Decimal(123456789000))
949
950    def test_implicit_from_string(self):
951        Decimal = self.decimal.Decimal
952        self.assertRaises(TypeError, eval, 'Decimal(5) + "3"', locals())
953
954    def test_implicit_from_float(self):
955        Decimal = self.decimal.Decimal
956        self.assertRaises(TypeError, eval, 'Decimal(5) + 2.2', locals())
957
958    def test_implicit_from_Decimal(self):
959        Decimal = self.decimal.Decimal
960        self.assertEqual(Decimal(5) + Decimal(45), Decimal(50))
961
962    def test_rop(self):
963        Decimal = self.decimal.Decimal
964
965        # Allow other classes to be trained to interact with Decimals
966        class E:
967            def __divmod__(self, other):
968                return 'divmod ' + str(other)
969            def __rdivmod__(self, other):
970                return str(other) + ' rdivmod'
971            def __lt__(self, other):
972                return 'lt ' + str(other)
973            def __gt__(self, other):
974                return 'gt ' + str(other)
975            def __le__(self, other):
976                return 'le ' + str(other)
977            def __ge__(self, other):
978                return 'ge ' + str(other)
979            def __eq__(self, other):
980                return 'eq ' + str(other)
981            def __ne__(self, other):
982                return 'ne ' + str(other)
983
984        self.assertEqual(divmod(E(), Decimal(10)), 'divmod 10')
985        self.assertEqual(divmod(Decimal(10), E()), '10 rdivmod')
986        self.assertEqual(eval('Decimal(10) < E()'), 'gt 10')
987        self.assertEqual(eval('Decimal(10) > E()'), 'lt 10')
988        self.assertEqual(eval('Decimal(10) <= E()'), 'ge 10')
989        self.assertEqual(eval('Decimal(10) >= E()'), 'le 10')
990        self.assertEqual(eval('Decimal(10) == E()'), 'eq 10')
991        self.assertEqual(eval('Decimal(10) != E()'), 'ne 10')
992
993        # insert operator methods and then exercise them
994        oplist = [
995            ('+', '__add__', '__radd__'),
996            ('-', '__sub__', '__rsub__'),
997            ('*', '__mul__', '__rmul__'),
998            ('%', '__mod__', '__rmod__'),
999            ('//', '__floordiv__', '__rfloordiv__'),
1000            ('**', '__pow__', '__rpow__')
1001        ]
1002        if 1/2 == 0:
1003            # testing with classic division, so add __div__
1004            oplist.append(('/', '__div__', '__rdiv__'))
1005        else:
1006            # testing with -Qnew, so add __truediv__
1007            oplist.append(('/', '__truediv__', '__rtruediv__'))
1008
1009        for sym, lop, rop in oplist:
1010            setattr(E, lop, lambda self, other: 'str' + lop + str(other))
1011            setattr(E, rop, lambda self, other: str(other) + rop + 'str')
1012            self.assertEqual(eval('E()' + sym + 'Decimal(10)'),
1013                             'str' + lop + '10')
1014            self.assertEqual(eval('Decimal(10)' + sym + 'E()'),
1015                             '10' + rop + 'str')
1016
1017class CImplicitConstructionTest(ImplicitConstructionTest):
1018    decimal = C
1019class PyImplicitConstructionTest(ImplicitConstructionTest):
1020    decimal = P
1021
1022class FormatTest(unittest.TestCase):
1023    '''Unit tests for the format function.'''
1024    def test_formatting(self):
1025        Decimal = self.decimal.Decimal
1026
1027        if py_minor <= 1 and self.decimal == P:
1028            raise unittest.SkipTest("requires Python 3.2")
1029
1030        # triples giving a format, a Decimal, and the expected result
1031        test_values = [
1032            ('e', '0E-15', '0e-15'),
1033            ('e', '2.3E-15', '2.3e-15'),
1034            ('e', '2.30E+2', '2.30e+2'), # preserve significant zeros
1035            ('e', '2.30000E-15', '2.30000e-15'),
1036            ('e', '1.23456789123456789e40', '1.23456789123456789e+40'),
1037            ('e', '1.5', '1.5e+0'),
1038            ('e', '0.15', '1.5e-1'),
1039            ('e', '0.015', '1.5e-2'),
1040            ('e', '0.0000000000015', '1.5e-12'),
1041            ('e', '15.0', '1.50e+1'),
1042            ('e', '-15', '-1.5e+1'),
1043            ('e', '0', '0e+0'),
1044            ('e', '0E1', '0e+1'),
1045            ('e', '0.0', '0e-1'),
1046            ('e', '0.00', '0e-2'),
1047            ('.6e', '0E-15', '0.000000e-9'),
1048            ('.6e', '0', '0.000000e+6'),
1049            ('.6e', '9.999999', '9.999999e+0'),
1050            ('.6e', '9.9999999', '1.000000e+1'),
1051            ('.6e', '-1.23e5', '-1.230000e+5'),
1052            ('.6e', '1.23456789e-3', '1.234568e-3'),
1053            ('f', '0', '0'),
1054            ('f', '0.0', '0.0'),
1055            ('f', '0E-2', '0.00'),
1056            ('f', '0.00E-8', '0.0000000000'),
1057            ('f', '0E1', '0'), # loses exponent information
1058            ('f', '3.2E1', '32'),
1059            ('f', '3.2E2', '320'),
1060            ('f', '3.20E2', '320'),
1061            ('f', '3.200E2', '320.0'),
1062            ('f', '3.2E-6', '0.0000032'),
1063            ('.6f', '0E-15', '0.000000'), # all zeros treated equally
1064            ('.6f', '0E1', '0.000000'),
1065            ('.6f', '0', '0.000000'),
1066            ('.0f', '0', '0'), # no decimal point
1067            ('.0f', '0e-2', '0'),
1068            ('.0f', '3.14159265', '3'),
1069            ('.1f', '3.14159265', '3.1'),
1070            ('.4f', '3.14159265', '3.1416'),
1071            ('.6f', '3.14159265', '3.141593'),
1072            ('.7f', '3.14159265', '3.1415926'), # round-half-even!
1073            ('.8f', '3.14159265', '3.14159265'),
1074            ('.9f', '3.14159265', '3.141592650'),
1075
1076            ('g', '0', '0'),
1077            ('g', '0.0', '0.0'),
1078            ('g', '0E1', '0e+1'),
1079            ('G', '0E1', '0E+1'),
1080            ('g', '0E-5', '0.00000'),
1081            ('g', '0E-6', '0.000000'),
1082            ('g', '0E-7', '0e-7'),
1083            ('g', '-0E2', '-0e+2'),
1084            ('.0g', '3.14159265', '3'),  # 0 sig fig -> 1 sig fig
1085            ('.1g', '3.14159265', '3'),
1086            ('.2g', '3.14159265', '3.1'),
1087            ('.5g', '3.14159265', '3.1416'),
1088            ('.7g', '3.14159265', '3.141593'),
1089            ('.8g', '3.14159265', '3.1415926'), # round-half-even!
1090            ('.9g', '3.14159265', '3.14159265'),
1091            ('.10g', '3.14159265', '3.14159265'), # don't pad
1092
1093            ('%', '0E1', '0%'),
1094            ('%', '0E0', '0%'),
1095            ('%', '0E-1', '0%'),
1096            ('%', '0E-2', '0%'),
1097            ('%', '0E-3', '0.0%'),
1098            ('%', '0E-4', '0.00%'),
1099
1100            ('.3%', '0', '0.000%'), # all zeros treated equally
1101            ('.3%', '0E10', '0.000%'),
1102            ('.3%', '0E-10', '0.000%'),
1103            ('.3%', '2.34', '234.000%'),
1104            ('.3%', '1.234567', '123.457%'),
1105            ('.0%', '1.23', '123%'),
1106
1107            ('e', 'NaN', 'NaN'),
1108            ('f', '-NaN123', '-NaN123'),
1109            ('+g', 'NaN456', '+NaN456'),
1110            ('.3e', 'Inf', 'Infinity'),
1111            ('.16f', '-Inf', '-Infinity'),
1112            ('.0g', '-sNaN', '-sNaN'),
1113
1114            ('', '1.00', '1.00'),
1115
1116            # test alignment and padding
1117            ('6', '123', '   123'),
1118            ('<6', '123', '123   '),
1119            ('>6', '123', '   123'),
1120            ('^6', '123', ' 123  '),
1121            ('=+6', '123', '+  123'),
1122            ('#<10', 'NaN', 'NaN#######'),
1123            ('#<10', '-4.3', '-4.3######'),
1124            ('#<+10', '0.0130', '+0.0130###'),
1125            ('#< 10', '0.0130', ' 0.0130###'),
1126            ('@>10', '-Inf', '@-Infinity'),
1127            ('#>5', '-Inf', '-Infinity'),
1128            ('?^5', '123', '?123?'),
1129            ('%^6', '123', '%123%%'),
1130            (' ^6', '-45.6', '-45.6 '),
1131            ('/=10', '-45.6', '-/////45.6'),
1132            ('/=+10', '45.6', '+/////45.6'),
1133            ('/= 10', '45.6', ' /////45.6'),
1134
1135            # thousands separator
1136            (',', '1234567', '1,234,567'),
1137            (',', '123456', '123,456'),
1138            (',', '12345', '12,345'),
1139            (',', '1234', '1,234'),
1140            (',', '123', '123'),
1141            (',', '12', '12'),
1142            (',', '1', '1'),
1143            (',', '0', '0'),
1144            (',', '-1234567', '-1,234,567'),
1145            (',', '-123456', '-123,456'),
1146            ('7,', '123456', '123,456'),
1147            ('8,', '123456', ' 123,456'),
1148            ('08,', '123456', '0,123,456'), # special case: extra 0 needed
1149            ('+08,', '123456', '+123,456'), # but not if there's a sign
1150            (' 08,', '123456', ' 123,456'),
1151            ('08,', '-123456', '-123,456'),
1152            ('+09,', '123456', '+0,123,456'),
1153            # ... with fractional part...
1154            ('07,', '1234.56', '1,234.56'),
1155            ('08,', '1234.56', '1,234.56'),
1156            ('09,', '1234.56', '01,234.56'),
1157            ('010,', '1234.56', '001,234.56'),
1158            ('011,', '1234.56', '0,001,234.56'),
1159            ('012,', '1234.56', '0,001,234.56'),
1160            ('08,.1f', '1234.5', '01,234.5'),
1161            # no thousands separators in fraction part
1162            (',', '1.23456789', '1.23456789'),
1163            (',%', '123.456789', '12,345.6789%'),
1164            (',e', '123456', '1.23456e+5'),
1165            (',E', '123456', '1.23456E+5'),
1166
1167            # issue 6850
1168            ('a=-7.0', '0.12345', 'aaaa0.1'),
1169            ]
1170        for fmt, d, result in test_values:
1171            self.assertEqual(format(Decimal(d), fmt), result)
1172
1173    def test_n_format(self):
1174        Decimal = self.decimal.Decimal
1175
1176        try:
1177            from locale import CHAR_MAX
1178        except ImportError:
1179            return
1180
1181        def make_grouping(lst):
1182            return unicode(''.join([chr(x) for x in lst])) if self.decimal == C else lst
1183
1184        def get_fmt(x, override=None, fmt='n'):
1185            if self.decimal == C:
1186                return Decimal(x).__format__(fmt, override)
1187            else:
1188                return Decimal(x).__format__(fmt, _localeconv=override)
1189
1190        # Set up some localeconv-like dictionaries
1191        en_US = {
1192            'decimal_point' : u'.',
1193            'grouping' : make_grouping([3, 3, 0]),
1194            'thousands_sep' : u','
1195            }
1196
1197        fr_FR = {
1198            'decimal_point' : u',',
1199            'grouping' : make_grouping([CHAR_MAX]),
1200            'thousands_sep' : u''
1201            }
1202
1203        ru_RU = {
1204            'decimal_point' : u',',
1205            'grouping': make_grouping([3, 3, 0]),
1206            'thousands_sep' : u' '
1207            }
1208
1209        crazy = {
1210            'decimal_point' : u'&',
1211            'grouping': make_grouping([1, 4, 2, CHAR_MAX]),
1212            'thousands_sep' : u'-'
1213            }
1214
1215        dotsep_wide = {
1216            'decimal_point' : b'\xc2\xbf'.decode('utf-8'),
1217            'grouping': make_grouping([3, 3, 0]),
1218            'thousands_sep' : b'\xc2\xb4'.decode('utf-8')
1219            }
1220
1221        self.assertEqual(get_fmt(Decimal('12.7'), en_US), '12.7')
1222        self.assertEqual(get_fmt(Decimal('12.7'), fr_FR), '12,7')
1223        self.assertEqual(get_fmt(Decimal('12.7'), ru_RU), '12,7')
1224        self.assertEqual(get_fmt(Decimal('12.7'), crazy), '1-2&7')
1225
1226        self.assertEqual(get_fmt(123456789, en_US), '123,456,789')
1227        self.assertEqual(get_fmt(123456789, fr_FR), '123456789')
1228        self.assertEqual(get_fmt(123456789, ru_RU), '123 456 789')
1229        self.assertEqual(get_fmt(1234567890123, crazy), '123456-78-9012-3')
1230
1231        self.assertEqual(get_fmt(123456789, en_US, '.6n'), '1.23457e+8')
1232        self.assertEqual(get_fmt(123456789, fr_FR, '.6n'), '1,23457e+8')
1233        self.assertEqual(get_fmt(123456789, ru_RU, '.6n'), '1,23457e+8')
1234        self.assertEqual(get_fmt(123456789, crazy, '.6n'), '1&23457e+8')
1235
1236        # zero padding
1237        self.assertEqual(get_fmt(1234, fr_FR, '03n'), '1234')
1238        self.assertEqual(get_fmt(1234, fr_FR, '04n'), '1234')
1239        self.assertEqual(get_fmt(1234, fr_FR, '05n'), '01234')
1240        self.assertEqual(get_fmt(1234, fr_FR, '06n'), '001234')
1241
1242        self.assertEqual(get_fmt(12345, en_US, '05n'), '12,345')
1243        self.assertEqual(get_fmt(12345, en_US, '06n'), '12,345')
1244        self.assertEqual(get_fmt(12345, en_US, '07n'), '012,345')
1245        self.assertEqual(get_fmt(12345, en_US, '08n'), '0,012,345')
1246        self.assertEqual(get_fmt(12345, en_US, '09n'), '0,012,345')
1247        self.assertEqual(get_fmt(12345, en_US, '010n'), '00,012,345')
1248
1249        self.assertEqual(get_fmt(123456, crazy, '06n'), '1-2345-6')
1250        self.assertEqual(get_fmt(123456, crazy, '07n'), '1-2345-6')
1251        self.assertEqual(get_fmt(123456, crazy, '08n'), '1-2345-6')
1252        self.assertEqual(get_fmt(123456, crazy, '09n'), '01-2345-6')
1253        self.assertEqual(get_fmt(123456, crazy, '010n'), '0-01-2345-6')
1254        self.assertEqual(get_fmt(123456, crazy, '011n'), '0-01-2345-6')
1255        self.assertEqual(get_fmt(123456, crazy, '012n'), '00-01-2345-6')
1256        self.assertEqual(get_fmt(123456, crazy, '013n'), '000-01-2345-6')
1257
1258        # wide char separator and decimal point
1259        if self.decimal == C:
1260            self.assertEqual(get_fmt(Decimal('-1.5'), dotsep_wide, '020n'),
1261                      '-0\xc2\xb4000\xc2\xb4000\xc2\xb4000\xc2\xb4001\xc2\xbf5')
1262
1263class CFormatTest(FormatTest):
1264    decimal = C
1265class PyFormatTest(FormatTest):
1266    decimal = P
1267
1268class ArithmeticOperatorsTest(unittest.TestCase):
1269    '''Unit tests for all arithmetic operators, binary and unary.'''
1270
1271    def test_addition(self):
1272        Decimal = self.decimal.Decimal
1273
1274        d1 = Decimal('-11.1')
1275        d2 = Decimal('22.2')
1276
1277        #two Decimals
1278        self.assertEqual(d1+d2, Decimal('11.1'))
1279        self.assertEqual(d2+d1, Decimal('11.1'))
1280
1281        #with other type, left
1282        c = d1 + 5
1283        self.assertEqual(c, Decimal('-6.1'))
1284        self.assertEqual(type(c), type(d1))
1285
1286        #with other type, right
1287        c = 5 + d1
1288        self.assertEqual(c, Decimal('-6.1'))
1289        self.assertEqual(type(c), type(d1))
1290
1291        #inline with decimal
1292        d1 += d2
1293        self.assertEqual(d1, Decimal('11.1'))
1294
1295        #inline with other type
1296        d1 += 5
1297        self.assertEqual(d1, Decimal('16.1'))
1298
1299    def test_subtraction(self):
1300        Decimal = self.decimal.Decimal
1301
1302        d1 = Decimal('-11.1')
1303        d2 = Decimal('22.2')
1304
1305        #two Decimals
1306        self.assertEqual(d1-d2, Decimal('-33.3'))
1307        self.assertEqual(d2-d1, Decimal('33.3'))
1308
1309        #with other type, left
1310        c = d1 - 5
1311        self.assertEqual(c, Decimal('-16.1'))
1312        self.assertEqual(type(c), type(d1))
1313
1314        #with other type, right
1315        c = 5 - d1
1316        self.assertEqual(c, Decimal('16.1'))
1317        self.assertEqual(type(c), type(d1))
1318
1319        #inline with decimal
1320        d1 -= d2
1321        self.assertEqual(d1, Decimal('-33.3'))
1322
1323        #inline with other type
1324        d1 -= 5
1325        self.assertEqual(d1, Decimal('-38.3'))
1326
1327    def test_multiplication(self):
1328        Decimal = self.decimal.Decimal
1329
1330        d1 = Decimal('-5')
1331        d2 = Decimal('3')
1332
1333        #two Decimals
1334        self.assertEqual(d1*d2, Decimal('-15'))
1335        self.assertEqual(d2*d1, Decimal('-15'))
1336
1337        #with other type, left
1338        c = d1 * 5
1339        self.assertEqual(c, Decimal('-25'))
1340        self.assertEqual(type(c), type(d1))
1341
1342        #with other type, right
1343        c = 5 * d1
1344        self.assertEqual(c, Decimal('-25'))
1345        self.assertEqual(type(c), type(d1))
1346
1347        #inline with decimal
1348        d1 *= d2
1349        self.assertEqual(d1, Decimal('-15'))
1350
1351        #inline with other type
1352        d1 *= 5
1353        self.assertEqual(d1, Decimal('-75'))
1354
1355    def test_division(self):
1356        Decimal = self.decimal.Decimal
1357
1358        d1 = Decimal('-5')
1359        d2 = Decimal('2')
1360
1361        #two Decimals
1362        self.assertEqual(d1/d2, Decimal('-2.5'))
1363        self.assertEqual(d2/d1, Decimal('-0.4'))
1364
1365        #with other type, left
1366        c = d1 / 4
1367        self.assertEqual(c, Decimal('-1.25'))
1368        self.assertEqual(type(c), type(d1))
1369
1370        #with other type, right
1371        c = 4 / d1
1372        self.assertEqual(c, Decimal('-0.8'))
1373        self.assertEqual(type(c), type(d1))
1374
1375        #inline with decimal
1376        d1 /= d2
1377        self.assertEqual(d1, Decimal('-2.5'))
1378
1379        #inline with other type
1380        d1 /= 4
1381        self.assertEqual(d1, Decimal('-0.625'))
1382
1383    def test_floor_division(self):
1384        Decimal = self.decimal.Decimal
1385
1386        d1 = Decimal('5')
1387        d2 = Decimal('2')
1388
1389        #two Decimals
1390        self.assertEqual(d1//d2, Decimal('2'))
1391        self.assertEqual(d2//d1, Decimal('0'))
1392
1393        #with other type, left
1394        c = d1 // 4
1395        self.assertEqual(c, Decimal('1'))
1396        self.assertEqual(type(c), type(d1))
1397
1398        #with other type, right
1399        c = 7 // d1
1400        self.assertEqual(c, Decimal('1'))
1401        self.assertEqual(type(c), type(d1))
1402
1403        #inline with decimal
1404        d1 //= d2
1405        self.assertEqual(d1, Decimal('2'))
1406
1407        #inline with other type
1408        d1 //= 2
1409        self.assertEqual(d1, Decimal('1'))
1410
1411    def test_powering(self):
1412        Decimal = self.decimal.Decimal
1413
1414        d1 = Decimal('5')
1415        d2 = Decimal('2')
1416
1417        #two Decimals
1418        self.assertEqual(d1**d2, Decimal('25'))
1419        self.assertEqual(d2**d1, Decimal('32'))
1420
1421        #with other type, left
1422        c = d1 ** 4
1423        self.assertEqual(c, Decimal('625'))
1424        self.assertEqual(type(c), type(d1))
1425
1426        #with other type, right
1427        c = 7 ** d1
1428        self.assertEqual(c, Decimal('16807'))
1429        self.assertEqual(type(c), type(d1))
1430
1431        #inline with decimal
1432        d1 **= d2
1433        self.assertEqual(d1, Decimal('25'))
1434
1435        #inline with other type
1436        d1 **= 4
1437        self.assertEqual(d1, Decimal('390625'))
1438
1439    def test_module(self):
1440        Decimal = self.decimal.Decimal
1441
1442        d1 = Decimal('5')
1443        d2 = Decimal('2')
1444
1445        #two Decimals
1446        self.assertEqual(d1%d2, Decimal('1'))
1447        self.assertEqual(d2%d1, Decimal('2'))
1448
1449        #with other type, left
1450        c = d1 % 4
1451        self.assertEqual(c, Decimal('1'))
1452        self.assertEqual(type(c), type(d1))
1453
1454        #with other type, right
1455        c = 7 % d1
1456        self.assertEqual(c, Decimal('2'))
1457        self.assertEqual(type(c), type(d1))
1458
1459        #inline with decimal
1460        d1 %= d2
1461        self.assertEqual(d1, Decimal('1'))
1462
1463        #inline with other type
1464        d1 %= 4
1465        self.assertEqual(d1, Decimal('1'))
1466
1467    def test_floor_div_module(self):
1468        Decimal = self.decimal.Decimal
1469
1470        d1 = Decimal('5')
1471        d2 = Decimal('2')
1472
1473        #two Decimals
1474        (p, q) = divmod(d1, d2)
1475        self.assertEqual(p, Decimal('2'))
1476        self.assertEqual(q, Decimal('1'))
1477        self.assertEqual(type(p), type(d1))
1478        self.assertEqual(type(q), type(d1))
1479
1480        #with other type, left
1481        (p, q) = divmod(d1, 4)
1482        self.assertEqual(p, Decimal('1'))
1483        self.assertEqual(q, Decimal('1'))
1484        self.assertEqual(type(p), type(d1))
1485        self.assertEqual(type(q), type(d1))
1486
1487        #with other type, right
1488        (p, q) = divmod(7, d1)
1489        self.assertEqual(p, Decimal('1'))
1490        self.assertEqual(q, Decimal('2'))
1491        self.assertEqual(type(p), type(d1))
1492        self.assertEqual(type(q), type(d1))
1493
1494    def test_unary_operators(self):
1495        Decimal = self.decimal.Decimal
1496
1497        self.assertEqual(+Decimal(45), Decimal(+45))           #  +
1498        self.assertEqual(-Decimal(45), Decimal(-45))           #  -
1499        self.assertEqual(abs(Decimal(45)), abs(Decimal(-45)))  # abs
1500
1501    def test_nan_comparisons(self):
1502        # comparisons involving signaling nans signal InvalidOperation
1503
1504        # order comparisons (<, <=, >, >=) involving only quiet nans
1505        # also signal InvalidOperation
1506
1507        # equality comparisons (==, !=) involving only quiet nans
1508        # don't signal, but return False or True respectively.
1509        Decimal = self.decimal.Decimal
1510        InvalidOperation = self.decimal.InvalidOperation
1511        localcontext = self.decimal.localcontext
1512
1513        if py_minor <= 1 and self.decimal == P:
1514            raise unittest.SkipTest("requires Python 3.2")
1515
1516        n = Decimal('NaN')
1517        s = Decimal('sNaN')
1518        i = Decimal('Inf')
1519        f = Decimal('2')
1520
1521        qnan_pairs = (n, n), (n, i), (i, n), (n, f), (f, n)
1522        snan_pairs = (s, n), (n, s), (s, i), (i, s), (s, f), (f, s), (s, s)
1523        order_ops = operator.lt, operator.le, operator.gt, operator.ge
1524        equality_ops = operator.eq, operator.ne
1525
1526        # results when InvalidOperation is not trapped
1527        for x, y in qnan_pairs + snan_pairs:
1528            for op in order_ops + equality_ops:
1529                got = op(x, y)
1530                expected = True if op is operator.ne else False
1531                self.assertTrue(expected is got)
1532
1533        # repeat the above, but this time trap the InvalidOperation
1534        with localcontext() as ctx:
1535            ctx.traps[InvalidOperation] = 1
1536
1537            for x, y in qnan_pairs:
1538                for op in equality_ops:
1539                    got = op(x, y)
1540                    expected = True if op is operator.ne else False
1541                    self.assertTrue(expected is got)
1542
1543            for x, y in snan_pairs:
1544                for op in equality_ops:
1545                    self.assertRaises(InvalidOperation, operator.eq, x, y)
1546                    self.assertRaises(InvalidOperation, operator.ne, x, y)
1547
1548            for x, y in qnan_pairs + snan_pairs:
1549                for op in order_ops:
1550                    self.assertRaises(InvalidOperation, op, x, y)
1551
1552    def test_copy_sign(self):
1553        Decimal = self.decimal.Decimal
1554
1555        if py_minor <= 1 and self.decimal == P:
1556            raise unittest.SkipTest("requires Python 3.2")
1557
1558        d = Decimal(1).copy_sign(Decimal(-2))
1559        self.assertEqual(Decimal(1).copy_sign(-2), d)
1560        self.assertRaises(TypeError, Decimal(1).copy_sign, '-2')
1561
1562class CArithmeticOperatorsTest(ArithmeticOperatorsTest):
1563    decimal = C
1564class PyArithmeticOperatorsTest(ArithmeticOperatorsTest):
1565    decimal = P
1566
1567# The following are two functions used to test threading in the next class
1568
1569def thfunc1(cls):
1570    Decimal = cls.decimal.Decimal
1571    InvalidOperation = cls.decimal.InvalidOperation
1572    DivisionByZero = cls.decimal.DivisionByZero
1573    Overflow = cls.decimal.Overflow
1574    Underflow = cls.decimal.Underflow
1575    Inexact = cls.decimal.Inexact
1576    getcontext = cls.decimal.getcontext
1577    localcontext = cls.decimal.localcontext
1578
1579    d1 = Decimal(1)
1580    d3 = Decimal(3)
1581    test1 = d1/d3
1582
1583    cls.finish1.set()
1584    cls.synchro.wait()
1585
1586    test2 = d1/d3
1587    with localcontext() as c2:
1588        cls.assertTrue(c2.flags[Inexact])
1589        cls.assertRaises(DivisionByZero, c2.divide, d1, 0)
1590        cls.assertTrue(c2.flags[DivisionByZero])
1591        with localcontext() as c3:
1592            cls.assertTrue(c3.flags[Inexact])
1593            cls.assertTrue(c3.flags[DivisionByZero])
1594            cls.assertRaises(InvalidOperation, c3.compare, d1, Decimal('sNaN'))
1595            cls.assertTrue(c3.flags[InvalidOperation])
1596            del c3
1597        cls.assertFalse(c2.flags[InvalidOperation])
1598        del c2
1599
1600    cls.assertEqual(test1, Decimal('0.333333333333333333333333'))
1601    cls.assertEqual(test2, Decimal('0.333333333333333333333333'))
1602
1603    c1 = getcontext()
1604    cls.assertTrue(c1.flags[Inexact])
1605    for sig in Overflow, Underflow, DivisionByZero, InvalidOperation:
1606        cls.assertFalse(c1.flags[sig])
1607    return
1608
1609def thfunc2(cls):
1610    Decimal = cls.decimal.Decimal
1611    InvalidOperation = cls.decimal.InvalidOperation
1612    DivisionByZero = cls.decimal.DivisionByZero
1613    Overflow = cls.decimal.Overflow
1614    Underflow = cls.decimal.Underflow
1615    Inexact = cls.decimal.Inexact
1616    getcontext = cls.decimal.getcontext
1617    localcontext = cls.decimal.localcontext
1618
1619    d1 = Decimal(1)
1620    d3 = Decimal(3)
1621    test1 = d1/d3
1622
1623    thiscontext = getcontext()
1624    thiscontext.prec = 18
1625    test2 = d1/d3
1626
1627    with localcontext() as c2:
1628        cls.assertTrue(c2.flags[Inexact])
1629        cls.assertRaises(Overflow, c2.multiply, Decimal('1e425000000'), 999)
1630        cls.assertTrue(c2.flags[Overflow])
1631        with localcontext(thiscontext) as c3:
1632            cls.assertTrue(c3.flags[Inexact])
1633            cls.assertFalse(c3.flags[Overflow])
1634            c3.traps[Underflow] = True
1635            cls.assertRaises(Underflow, c3.divide, Decimal('1e-425000000'), 999)
1636            cls.assertTrue(c3.flags[Underflow])
1637            del c3
1638        cls.assertFalse(c2.flags[Underflow])
1639        cls.assertFalse(c2.traps[Underflow])
1640        del c2
1641
1642    cls.synchro.set()
1643    cls.finish2.set()
1644
1645    cls.assertEqual(test1, Decimal('0.333333333333333333333333'))
1646    cls.assertEqual(test2, Decimal('0.333333333333333333'))
1647
1648    cls.assertFalse(thiscontext.traps[Underflow])
1649    cls.assertTrue(thiscontext.flags[Inexact])
1650    for sig in Overflow, Underflow, DivisionByZero, InvalidOperation:
1651        cls.assertFalse(thiscontext.flags[sig])
1652    return
1653
1654class ThreadingTest(unittest.TestCase):
1655    '''Unit tests for thread local contexts in Decimal.'''
1656
1657    # Take care executing this test from IDLE, there's an issue in threading
1658    # that hangs IDLE and I couldn't find it
1659
1660    def test_threading(self):
1661        if threading is None:
1662            return
1663        if self.decimal == C and not self.decimal.HAVE_THREADS:
1664            return
1665
1666        DefaultContext = self.decimal.DefaultContext
1667
1668        # Test the "threading isolation" of a Context. Also test changing
1669        # the DefaultContext, which acts as a template for the thread-local
1670        # contexts.
1671        save_prec = DefaultContext.prec
1672        save_emax = DefaultContext.Emax
1673        save_emin = DefaultContext.Emin
1674        DefaultContext.prec = 24
1675        DefaultContext.Emax = 425000000
1676        DefaultContext.Emin = -425000000
1677
1678        with protectfail():
1679            self.synchro = threading.Event()
1680            self.finish1 = threading.Event()
1681            self.finish2 = threading.Event()
1682
1683            th1 = threading.Thread(target=thfunc1, args=(self,))
1684            th2 = threading.Thread(target=thfunc2, args=(self,))
1685
1686            th1.start()
1687            th2.start()
1688
1689            self.finish1.wait()
1690            self.finish2.wait()
1691
1692        for sig in Signals[self.decimal]:
1693            self.assertFalse(DefaultContext.flags[sig])
1694
1695        DefaultContext.prec = save_prec
1696        DefaultContext.Emax = save_emax
1697        DefaultContext.Emin = save_emin
1698        return
1699
1700class CThreadingTest(ThreadingTest):
1701    decimal = C
1702class PyThreadingTest(ThreadingTest):
1703    decimal = P
1704
1705class UsabilityTest(unittest.TestCase):
1706    '''Unit tests for Usability cases of Decimal.'''
1707
1708    def test_comparison_operators(self):
1709        if hasattr(C, 'setfailpoint'):
1710            random.seed(randseed)
1711
1712        Decimal = self.decimal.Decimal
1713
1714        da = Decimal('23.42')
1715        db = Decimal('23.42')
1716        dc = Decimal('45')
1717
1718        #two Decimals
1719        self.assertTrue(dc > da)
1720        self.assertTrue(dc >= da)
1721        self.assertTrue(da < dc)
1722        self.assertTrue(da <= dc)
1723        self.assertTrue(da == db)
1724        self.assertTrue(da != dc)
1725        self.assertTrue(da <= db)
1726        self.assertTrue(da >= db)
1727        self.assertEqual(cmp(dc,da), 1)
1728        self.assertEqual(cmp(da,dc), -1)
1729        self.assertEqual(cmp(da,db), 0)
1730
1731        #a Decimal and an int
1732        self.assertTrue(dc > 23)
1733        self.assertTrue(23 < dc)
1734        self.assertTrue(dc == 45)
1735        self.assertEqual(cmp(dc,23), 1)
1736        self.assertEqual(cmp(23,dc), -1)
1737        self.assertEqual(cmp(dc,45), 0)
1738
1739        #a Decimal and uncomparable
1740        self.assertNotEqual(da, 'ugly')
1741        self.assertNotEqual(da, 32.7)
1742        self.assertNotEqual(da, object())
1743        self.assertNotEqual(da, object)
1744
1745        # sortable
1746        a = list(map(Decimal, range(100)))
1747        b =  a[:]
1748        random.shuffle(a)
1749        a.sort()
1750        self.assertEqual(a, b)
1751
1752        # with None
1753        self.assertFalse(Decimal(1) < None)
1754        self.assertTrue(Decimal(1) > None)
1755
1756        # long
1757        x = 28847289182731823123121213123823129L
1758        self.assertTrue(dc < x)
1759        self.assertTrue(dc <= x)
1760        self.assertTrue(dc > -x)
1761        self.assertTrue(dc >= -x)
1762        self.assertTrue(dc != -x)
1763        self.assertTrue(Decimal(x) == x)
1764
1765    def test_decimal_float_comparison(self):
1766        Decimal = self.decimal.Decimal
1767        Context = self.decimal.Context
1768        localcontext = self.decimal.localcontext
1769
1770        def assert_attr(a, b, attr, context, signal=None):
1771            context.clear_flags()
1772            f = getattr(a, attr)
1773            if self.decimal == C:
1774                if signal == C.FloatOperation:
1775                    self.assertRaises(signal, f, b)
1776                elif py_minor <= 6:
1777                    # The actual TypeError is raised by
1778                    # the caller of the comparison methods.
1779                    self.assertTrue(f(b) is NotImplemented)
1780                else:
1781                    self.assertTrue(f(b) is True)
1782                self.assertTrue(context.flags[C.FloatOperation])
1783            else:
1784                if py_minor <= 6:
1785                    self.assertTrue(f(b) is NotImplemented)
1786                else:
1787                    self.assertTrue(f(b) is True)
1788
1789        small_d = Decimal('0.25')
1790        big_d = Decimal('3.0')
1791        small_f = 0.25
1792        big_f = 3.0
1793
1794        zero_d = Decimal('0.0')
1795        neg_zero_d = Decimal('-0.0')
1796        zero_f = 0.0
1797        neg_zero_f = -0.0
1798
1799        inf_d = Decimal('Infinity')
1800        neg_inf_d = Decimal('-Infinity')
1801        inf_f = float('inf')
1802        neg_inf_f = float('-inf')
1803
1804        def doit(c, signal=None):
1805            # Order
1806            for attr in '__lt__', '__le__':
1807                assert_attr(small_d, big_f, attr, c, signal)
1808
1809            for attr in '__gt__', '__ge__':
1810                assert_attr(big_d, small_f, attr, c, signal)
1811
1812            # Equality
1813            assert_attr(small_d, small_f, '__eq__', c, None)
1814
1815            assert_attr(neg_zero_d, neg_zero_f, '__eq__', c, None)
1816            assert_attr(neg_zero_d, zero_f, '__eq__', c, None)
1817
1818            assert_attr(zero_d, neg_zero_f, '__eq__', c, None)
1819            assert_attr(zero_d, zero_f, '__eq__', c, None)
1820
1821            assert_attr(neg_inf_d, neg_inf_f, '__eq__', c, None)
1822            assert_attr(inf_d, inf_f, '__eq__', c, None)
1823
1824            # Inequality
1825            assert_attr(small_d, big_f, '__ne__', c, None)
1826
1827            assert_attr(Decimal('0.1'), 0.1, '__ne__', c, None)
1828
1829            assert_attr(neg_inf_d, inf_f, '__ne__', c, None)
1830            assert_attr(inf_d, neg_inf_f, '__ne__', c, None)
1831
1832            assert_attr(Decimal('NaN'), float('nan'), '__ne__', c, None)
1833
1834        def test_containers(c, signal):
1835            c.clear_flags()
1836            s = set([100.0, Decimal('100.0')])
1837            expected_len = 2 if py_minor <= 6 else 1
1838            self.assertEqual(len(s), expected_len)
1839            self.assertTrue(c.flags[C.FloatOperation])
1840
1841            c.clear_flags()
1842            if signal:
1843                self.assertRaises(signal, sorted, [1.0, Decimal('10.0')])
1844            else:
1845                s = sorted([10.0, Decimal('10.0')])
1846            self.assertTrue(c.flags[C.FloatOperation])
1847
1848            c.clear_flags()
1849            b = 10.0 in [Decimal('10.0'), 1.0]
1850            self.assertTrue(c.flags[C.FloatOperation])
1851
1852            c.clear_flags()
1853            b = 10.0 in {Decimal('10.0'):'a', 1.0:'b'}
1854            self.assertTrue(c.flags[C.FloatOperation])
1855
1856        if self.decimal == C:
1857            nc = Context()
1858            with localcontext(nc) as c:
1859                self.assertFalse(c.traps[C.FloatOperation])
1860                doit(c, signal=None)
1861                test_containers(c, None)
1862
1863                c.traps[C.FloatOperation] = True
1864                doit(c, signal=C.FloatOperation)
1865                test_containers(c, C.FloatOperation)
1866        else:
1867            # decimal.py does not have the FloatOperation signal.
1868            nc = Context()
1869            with localcontext(nc) as c:
1870                doit(c, signal=False)
1871
1872    def test_decimal_complex_comparison(self):
1873        Decimal = self.decimal.Decimal
1874
1875        da = Decimal('0.25')
1876        db = Decimal('3.0')
1877        self.assertNotEqual(da, (1.5+0j))
1878        self.assertNotEqual((1.5+0j), da)
1879
1880        if py_minor >= 8:
1881            self.assertEqual(da, (0.25+0j))
1882            self.assertEqual((0.25+0j), da)
1883            self.assertEqual((3.0+0j), db)
1884            self.assertEqual(db, (3.0+0j))
1885        else:
1886            self.assertNotEqual(da, (0.25+0j))
1887            self.assertNotEqual((0.25+0j), da)
1888            self.assertNotEqual((3.0+0j), db)
1889            self.assertNotEqual(db, (3.0+0j))
1890
1891        self.assertNotEqual(db, (3.0+1j))
1892        self.assertNotEqual((3.0+1j), db)
1893
1894        self.assertTrue(db.__lt__(3.0+0j) is NotImplemented)
1895        self.assertTrue(db.__le__(3.0+0j) is NotImplemented)
1896        self.assertTrue(db.__gt__(3.0+0j) is NotImplemented)
1897        self.assertTrue(db.__le__(3.0+0j) is NotImplemented)
1898
1899    def test_decimal_fraction_comparison(self):
1900        D = self.decimal.Decimal
1901        F = fractions.Fraction
1902        Context = self.decimal.Context
1903        localcontext = self.decimal.localcontext
1904        InvalidOperation = self.decimal.InvalidOperation
1905
1906
1907        emax = C.MAX_EMAX if C else 999999999
1908        emin = C.MIN_EMIN if C else -999999999
1909        etiny = C.MIN_ETINY if C else -1999999997
1910        c = Context(Emax=emax, Emin=emin)
1911
1912        with localcontext(c):
1913            c.prec = emax
1914            if py_minor >= 8:
1915                self.assertTrue(D(0) < F(1,9999999999999999999999999999999999999))
1916                self.assertTrue(F(-1,9999999999999999999999999999999999999) < D(0))
1917                self.assertTrue(F(0,1) < D("1e" + str(etiny)))
1918                self.assertTrue(D("-1e" + str(etiny)) < F(0,1))
1919                self.assertTrue(F(0,9999999999999999999999999) < D("1e" + str(etiny)))
1920                self.assertTrue(D("-1e" + str(etiny)) < F(0,9999999999999999999999999))
1921            else:
1922                self.assertTrue(NotImplemented is D(0).__lt__(F(1,1)))
1923                self.assertTrue(NotImplemented is D(0).__le__(F(1,1)))
1924                self.assertTrue(NotImplemented is D(0).__gt__(F(1,1)))
1925                self.assertTrue(NotImplemented is D(0).__ge__(F(1,1)))
1926
1927            if py_minor >= 8:
1928                self.assertEqual(D("0.1"), F(1,10))
1929                self.assertEqual(F(1,10), D("0.1"))
1930            else:
1931                self.assertNotEqual(D("0.1"), F(1,10))
1932                self.assertNotEqual(F(1,10), D("0.1"))
1933
1934            c.prec = 300
1935            self.assertNotEqual(D(1)/3, F(1,3))
1936            self.assertNotEqual(F(1,3), D(1)/3)
1937
1938            if py_minor >= 8:
1939                self.assertTrue(F(120984237, 9999999999) <= D("9e" + str(emax)))
1940                self.assertTrue(D("9e" + str(emax)) >= F(120984237, 9999999999))
1941
1942                self.assertTrue(D('inf') > F(99999999999,123))
1943                self.assertTrue(D('inf') > F(-99999999999,123))
1944                self.assertTrue(D('-inf') < F(99999999999,123))
1945                self.assertTrue(D('-inf') < F(-99999999999,123))
1946
1947                self.assertRaises(InvalidOperation, D('nan').__gt__, F(-9,123))
1948
1949            self.assertTrue(NotImplemented is F(-9,123).__lt__(D('nan')))
1950            self.assertNotEqual(D('nan'), F(-9,123))
1951            self.assertNotEqual(F(-9,123), D('nan'))
1952
1953    def test_copy_and_deepcopy_methods(self):
1954        Decimal = self.decimal.Decimal
1955
1956        d = Decimal('43.24')
1957        c = copy.copy(d)
1958        self.assertEqual(id(c), id(d))
1959        dc = copy.deepcopy(d)
1960        self.assertEqual(id(dc), id(d))
1961
1962    def test_hash_method(self):
1963        if hasattr(C, 'setfailpoint'):
1964            random.seed(randseed)
1965
1966        Decimal = self.decimal.Decimal
1967        localcontext = self.decimal.localcontext
1968
1969        def hashit(d):
1970            a = hash(d)
1971            b = d.__hash__()
1972            self.assertEqual(a, b)
1973            return a
1974
1975        #just that it's hashable
1976        hashit(Decimal(23))
1977        hashit(Decimal('Infinity'))
1978        hashit(Decimal('-Infinity'))
1979        if py_minor >= 7:
1980            hashit(Decimal('nan123'))
1981            hashit(Decimal('-NaN'))
1982
1983        test_values = [Decimal(sign*(2**m + n))
1984                       for m in [0, 14, 15, 16, 17, 30, 31,
1985                                 32, 33, 61, 62, 63, 64, 65, 66]
1986                       for n in range(-10, 10)
1987                       for sign in [-1, 1]]
1988        if hasattr(C, 'setfailpoint'):
1989            test_values = random.sample(test_values, 10)
1990        test_values.extend([
1991                Decimal("-1"), # ==> -2
1992                Decimal("-0"), # zeros
1993                Decimal("0.00"),
1994                Decimal("-0.000"),
1995                Decimal("0E10"),
1996                Decimal("-0E12"),
1997                Decimal("10.0"), # negative exponent
1998                Decimal("-23.00000"),
1999                Decimal("1230E100"), # positive exponent
2000                Decimal("-4.5678E50"),
2001                # a value for which hash(n) != hash(n % (2**64-1))
2002                # in Python pre-2.6
2003                Decimal(2**64 + 2**32 - 1),
2004                # selection of values which fail with the old (before
2005                # version 2.6) long.__hash__
2006                Decimal("1.634E100"),
2007                Decimal("90.697E100"),
2008                Decimal("188.83E100"),
2009                Decimal("1652.9E100"),
2010                Decimal("56531E100"),
2011                ])
2012
2013        # check that hash(d) == hash(int(d)) for integral values
2014        for value in test_values:
2015            self.assertEqual(hashit(value), hashit(int(value)))
2016
2017        #the same hash that to an int
2018        self.assertEqual(hashit(Decimal(23)), hashit(23))
2019        self.assertRaises(TypeError, hash, Decimal('sNaN'))
2020        self.assertTrue(hashit(Decimal('Inf')))
2021        self.assertTrue(hashit(Decimal('-Inf')))
2022
2023        if py_minor >= 7:
2024            # check that the hashes of a Decimal float match when they
2025            # represent exactly the same values
2026            test_strings = ['inf', '-Inf', '0.0', '-.0e1',
2027                            '34.0', '2.5', '112390.625', '-0.515625']
2028            for s in test_strings:
2029                f = float(s)
2030                d = Decimal(s)
2031                self.assertEqual(hashit(f), hashit(d))
2032
2033        with localcontext() as c:
2034            # check that the value of the hash doesn't depend on the
2035            # current context (issue #1757)
2036            x = Decimal("123456789.1")
2037
2038            c.prec = 6
2039            h1 = hashit(x)
2040            c.prec = 10
2041            h2 = hashit(x)
2042            c.prec = 16
2043            h3 = hashit(x)
2044
2045            self.assertEqual(h1, h2)
2046            self.assertEqual(h1, h3)
2047
2048            c.prec = 10000
2049            x = 1100 ** 1248
2050            self.assertEqual(hashit(Decimal(x)), hashit(x))
2051
2052    def test_min_and_max_methods(self):
2053        Decimal = self.decimal.Decimal
2054
2055        d1 = Decimal('15.32')
2056        d2 = Decimal('28.5')
2057        l1 = 15
2058        l2 = 28
2059
2060        #between Decimals
2061        self.assertTrue(min(d1,d2) is d1)
2062        self.assertTrue(min(d2,d1) is d1)
2063        self.assertTrue(max(d1,d2) is d2)
2064        self.assertTrue(max(d2,d1) is d2)
2065
2066        #between Decimal and long
2067        self.assertTrue(min(d1,l2) is d1)
2068        self.assertTrue(min(l2,d1) is d1)
2069        self.assertTrue(max(l1,d2) is d2)
2070        self.assertTrue(max(d2,l1) is d2)
2071
2072    def test_as_nonzero(self):
2073        Decimal = self.decimal.Decimal
2074
2075        #as false
2076        self.assertFalse(Decimal(0))
2077        #as true
2078        self.assertTrue(Decimal('0.372'))
2079
2080    def test_tostring_methods(self):
2081        #Test str and repr methods.
2082        Decimal = self.decimal.Decimal
2083
2084        d = Decimal('15.32')
2085        self.assertEqual(str(d), '15.32')               # str
2086        self.assertEqual(repr(d), "Decimal('15.32')")   # repr
2087
2088        # result type of string methods should be str, not unicode
2089        unicode_inputs = [u'123.4', u'0.5E2', u'Infinity', u'sNaN',
2090                          u'-0.0E100', u'-NaN001', u'-Inf']
2091
2092        for u in unicode_inputs:
2093            d = Decimal(u)
2094            self.assertEqual(type(str(d)), str)
2095            self.assertEqual(type(repr(d)), str)
2096            self.assertEqual(type(d.to_eng_string()), str)
2097
2098    def test_tonum_methods(self):
2099        #Test float, int and long methods.
2100        Decimal = self.decimal.Decimal
2101
2102        d1 = Decimal('66')
2103        d2 = Decimal('15.32')
2104
2105        #int
2106        self.assertEqual(int(d1), 66)
2107        self.assertEqual(int(d2), 15)
2108
2109        #long
2110        self.assertEqual(long(d1), 66)
2111        self.assertEqual(long(d2), 15)
2112
2113        #float
2114        self.assertEqual(float(d1), 66)
2115        self.assertEqual(float(d2), 15.32)
2116
2117    def test_eval_round_trip(self):
2118        Decimal = self.decimal.Decimal
2119
2120        #with zero
2121        d = Decimal( (0, (0,), 0) )
2122        self.assertEqual(d, eval(repr(d)))
2123
2124        #int
2125        d = Decimal( (1, (4, 5), 0) )
2126        self.assertEqual(d, eval(repr(d)))
2127
2128        #float
2129        d = Decimal( (0, (4, 5, 3, 4), -2) )
2130        self.assertEqual(d, eval(repr(d)))
2131
2132        #weird
2133        d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
2134        self.assertEqual(d, eval(repr(d)))
2135
2136    def test_as_tuple(self):
2137        Decimal = self.decimal.Decimal
2138
2139        #with zero
2140        d = Decimal(0)
2141        self.assertEqual(d.as_tuple(), (0, (0,), 0) )
2142
2143        #int
2144        d = Decimal(-45)
2145        self.assertEqual(d.as_tuple(), (1, (4, 5), 0) )
2146
2147        #complicated string
2148        d = Decimal("-4.34913534E-17")
2149        self.assertEqual(d.as_tuple(), (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
2150
2151        # XXX non-compliant infinity payload.
2152        d = Decimal("Infinity")
2153        self.assertEqual(d.as_tuple(), (0, (0,), 'F') )
2154
2155        #leading zeros in coefficient should be stripped
2156        d = Decimal( (0, (0, 0, 4, 0, 5, 3, 4), -2) )
2157        self.assertEqual(d.as_tuple(), (0, (4, 0, 5, 3, 4), -2) )
2158        d = Decimal( (1, (0, 0, 0), 37) )
2159        self.assertEqual(d.as_tuple(), (1, (0,), 37))
2160        d = Decimal( (1, (), 37) )
2161        self.assertEqual(d.as_tuple(), (1, (0,), 37))
2162
2163        #leading zeros in NaN diagnostic info should be stripped
2164        d = Decimal( (0, (0, 0, 4, 0, 5, 3, 4), 'n') )
2165        self.assertEqual(d.as_tuple(), (0, (4, 0, 5, 3, 4), 'n') )
2166        d = Decimal( (1, (0, 0, 0), 'N') )
2167        self.assertEqual(d.as_tuple(), (1, (), 'N') )
2168        d = Decimal( (1, (), 'n') )
2169        self.assertEqual(d.as_tuple(), (1, (), 'n') )
2170
2171        # XXX coefficient in infinity should raise an error
2172        if self.decimal == P:
2173            d = Decimal( (0, (4, 5, 3, 4), 'F') )
2174            self.assertEqual(d.as_tuple(), (0, (0,), 'F'))
2175            d = Decimal( (1, (0, 2, 7, 1), 'F') )
2176            self.assertEqual(d.as_tuple(), (1, (0,), 'F'))
2177
2178    def test_subclassing(self):
2179        # Different behaviours when subclassing Decimal
2180        Decimal = self.decimal.Decimal
2181
2182        class MyDecimal(Decimal):
2183            pass
2184
2185        d1 = MyDecimal(1)
2186        d2 = MyDecimal(2)
2187        d = d1 + d2
2188        self.assertTrue(type(d) is Decimal)
2189
2190        d = d1.max(d2)
2191        self.assertTrue(type(d) is Decimal)
2192
2193        d = copy.copy(d1)
2194        self.assertTrue(type(d) is MyDecimal)
2195        self.assertEqual(d, d1)
2196
2197        d = copy.deepcopy(d1)
2198        self.assertTrue(type(d) is MyDecimal)
2199        self.assertEqual(d, d1)
2200
2201    def test_implicit_context(self):
2202        Decimal = self.decimal.Decimal
2203        getcontext = self.decimal.getcontext
2204
2205        # Check results when context given implicitly.  (Issue 2478)
2206        c = getcontext()
2207        self.assertEqual(str(Decimal(0).sqrt()),
2208                         str(c.sqrt(Decimal(0))))
2209
2210    def test_conversions_from_int(self):
2211        # Check that methods taking a second Decimal argument will
2212        # always accept an integer in place of a Decimal.
2213        Decimal = self.decimal.Decimal
2214
2215        self.assertEqual(Decimal(4).compare(3),
2216                         Decimal(4).compare(Decimal(3)))
2217        self.assertEqual(Decimal(4).compare_signal(3),
2218                         Decimal(4).compare_signal(Decimal(3)))
2219        self.assertEqual(Decimal(4).compare_total(3),
2220                         Decimal(4).compare_total(Decimal(3)))
2221        self.assertEqual(Decimal(4).compare_total_mag(3),
2222                         Decimal(4).compare_total_mag(Decimal(3)))
2223        self.assertEqual(Decimal(10101).logical_and(1001),
2224                         Decimal(10101).logical_and(Decimal(1001)))
2225        self.assertEqual(Decimal(10101).logical_or(1001),
2226                         Decimal(10101).logical_or(Decimal(1001)))
2227        self.assertEqual(Decimal(10101).logical_xor(1001),
2228                         Decimal(10101).logical_xor(Decimal(1001)))
2229        self.assertEqual(Decimal(567).max(123),
2230                         Decimal(567).max(Decimal(123)))
2231        self.assertEqual(Decimal(567).max_mag(123),
2232                         Decimal(567).max_mag(Decimal(123)))
2233        self.assertEqual(Decimal(567).min(123),
2234                         Decimal(567).min(Decimal(123)))
2235        self.assertEqual(Decimal(567).min_mag(123),
2236                         Decimal(567).min_mag(Decimal(123)))
2237        self.assertEqual(Decimal(567).next_toward(123),
2238                         Decimal(567).next_toward(Decimal(123)))
2239        self.assertEqual(Decimal(1234).quantize(100),
2240                         Decimal(1234).quantize(Decimal(100)))
2241        self.assertEqual(Decimal(768).remainder_near(1234),
2242                         Decimal(768).remainder_near(Decimal(1234)))
2243        self.assertEqual(Decimal(123).rotate(1),
2244                         Decimal(123).rotate(Decimal(1)))
2245        self.assertEqual(Decimal(1234).same_quantum(1000),
2246                         Decimal(1234).same_quantum(Decimal(1000)))
2247        self.assertEqual(Decimal('9.123').scaleb(-100),
2248                         Decimal('9.123').scaleb(Decimal(-100)))
2249        self.assertEqual(Decimal(456).shift(-1),
2250                         Decimal(456).shift(Decimal(-1)))
2251
2252        self.assertEqual(Decimal(-12).fma(Decimal(45), 67),
2253                         Decimal(-12).fma(Decimal(45), Decimal(67)))
2254        self.assertEqual(Decimal(-12).fma(45, 67),
2255                         Decimal(-12).fma(Decimal(45), Decimal(67)))
2256        self.assertEqual(Decimal(-12).fma(45, Decimal(67)),
2257                         Decimal(-12).fma(Decimal(45), Decimal(67)))
2258
2259class CUsabilityTest(UsabilityTest):
2260    decimal = C
2261class PyUsabilityTest(UsabilityTest):
2262    decimal = P
2263
2264class PythonAPItests(unittest.TestCase):
2265
2266    def test_abc(self):
2267        Decimal = self.decimal.Decimal
2268
2269        self.assertTrue(issubclass(Decimal, numbers.Number))
2270        self.assertTrue(not issubclass(Decimal, numbers.Real))
2271        self.assertTrue(isinstance(Decimal(0), numbers.Number))
2272        self.assertTrue(not isinstance(Decimal(0), numbers.Real))
2273
2274    def test_pickle(self):
2275        Decimal = self.decimal.Decimal
2276
2277        # Round trip
2278        d = Decimal('-3.141590000')
2279        p = pickle.dumps(d)
2280        e = pickle.loads(p)
2281        self.assertEqual(d, e)
2282
2283    def test_int(self):
2284        Decimal = self.decimal.Decimal
2285        ROUND_DOWN = self.decimal.ROUND_DOWN
2286
2287        lim = 10 if hasattr(C, 'setfailpoint') else 250
2288        for x in range(-lim, lim):
2289            s = '%0.2f' % (x / 100.0)
2290            # should work the same as for floats
2291            self.assertEqual(int(Decimal(s)), int(float(s)))
2292            # should work the same as to_integral in the ROUND_DOWN mode
2293            d = Decimal(s)
2294            r = d.to_integral(ROUND_DOWN)
2295            self.assertEqual(Decimal(int(d)), r)
2296
2297        self.assertRaises(ValueError, int, Decimal('-nan'))
2298        self.assertRaises(ValueError, int, Decimal('snan'))
2299        self.assertRaises(OverflowError, int, Decimal('inf'))
2300        self.assertRaises(OverflowError, int, Decimal('-inf'))
2301
2302        self.assertRaises(ValueError, long, Decimal('-nan'))
2303        self.assertRaises(ValueError, long, Decimal('snan'))
2304        self.assertRaises(OverflowError, long, Decimal('inf'))
2305        self.assertRaises(OverflowError, long, Decimal('-inf'))
2306
2307    def test_trunc(self):
2308        Decimal = self.decimal.Decimal
2309        ROUND_DOWN = self.decimal.ROUND_DOWN
2310
2311        lim = 10 if hasattr(C, 'setfailpoint') else 250
2312        for x in range(-lim, lim):
2313            s = '%0.2f' % (x / 100.0)
2314            # should work the same as for floats
2315            self.assertEqual(int(Decimal(s)), int(float(s)))
2316            # should work the same as to_integral in the ROUND_DOWN mode
2317            d = Decimal(s)
2318            r = d.to_integral(ROUND_DOWN)
2319            self.assertEqual(Decimal(math.trunc(d)), r)
2320
2321    def test_from_float(self):
2322        if hasattr(C, 'setfailpoint'):
2323            random.seed(randseed)
2324
2325        Decimal = self.decimal.Decimal
2326
2327        class MyDecimal(Decimal):
2328            pass
2329
2330        self.assertTrue(issubclass(MyDecimal, Decimal))
2331
2332        r = MyDecimal.from_float(0.1)
2333        self.assertEqual(type(r), MyDecimal)
2334        self.assertEqual(str(r),
2335                '0.1000000000000000055511151231257827021181583404541015625')
2336        bigint = 12345678901234567890123456789
2337        self.assertEqual(MyDecimal.from_float(bigint), MyDecimal(bigint))
2338        self.assertTrue(MyDecimal.from_float(float('nan')).is_qnan())
2339        self.assertTrue(MyDecimal.from_float(float('inf')).is_infinite())
2340        self.assertTrue(MyDecimal.from_float(float('-inf')).is_infinite())
2341        self.assertEqual(str(MyDecimal.from_float(float('nan'))),
2342                         str(Decimal('NaN')))
2343        self.assertEqual(str(MyDecimal.from_float(float('inf'))),
2344                         str(Decimal('Infinity')))
2345        self.assertEqual(str(MyDecimal.from_float(float('-inf'))),
2346                         str(Decimal('-Infinity')))
2347        self.assertRaises(TypeError, MyDecimal.from_float, 'abc')
2348        lim = 10 if hasattr(C, 'setfailpoint') else 200
2349        for i in range(lim):
2350            x = random.expovariate(0.01) * (random.random() * 2.0 - 1.0)
2351            self.assertEqual(x, float(MyDecimal.from_float(x))) # roundtrip
2352
2353    def test_create_decimal_from_float(self):
2354        Decimal = self.decimal.Decimal
2355        Context = self.decimal.Context
2356        ROUND_DOWN = self.decimal.ROUND_DOWN
2357        ROUND_UP = self.decimal.ROUND_UP
2358        Inexact = self.decimal.Inexact
2359
2360        context = Context(prec=5, rounding=ROUND_DOWN)
2361        self.assertEqual(
2362            context.create_decimal_from_float(math.pi),
2363            Decimal('3.1415')
2364        )
2365        context = Context(prec=5, rounding=ROUND_UP)
2366        self.assertEqual(
2367            context.create_decimal_from_float(math.pi),
2368            Decimal('3.1416')
2369        )
2370        context = Context(prec=5, traps=[Inexact])
2371        self.assertRaises(
2372            Inexact,
2373            context.create_decimal_from_float,
2374            math.pi
2375        )
2376        self.assertEqual(repr(context.create_decimal_from_float(-0.0)),
2377                         "Decimal('-0')")
2378        self.assertEqual(repr(context.create_decimal_from_float(1.0)),
2379                         "Decimal('1')")
2380        self.assertEqual(repr(context.create_decimal_from_float(10)),
2381                         "Decimal('10')")
2382
2383    def test_quantize(self):
2384        Decimal = self.decimal.Decimal
2385        Context = self.decimal.Context
2386        InvalidOperation = self.decimal.InvalidOperation
2387        ROUND_DOWN = self.decimal.ROUND_DOWN
2388
2389        c = Context(Emax=99999, Emin=-99999)
2390        self.assertEqual(
2391            Decimal('7.335').quantize(Decimal('.01')),
2392            Decimal('7.34')
2393        )
2394        self.assertEqual(
2395            Decimal('7.335').quantize(Decimal('.01'), rounding=ROUND_DOWN),
2396            Decimal('7.33')
2397        )
2398        self.assertRaises(
2399            InvalidOperation,
2400            Decimal("10e99999").quantize, Decimal('1e100000'), context=c
2401        )
2402
2403        c = Context()
2404        d = Decimal("0.871831e800")
2405        x = d.quantize(context=c, exp=Decimal("1e797"), rounding=ROUND_DOWN)
2406        self.assertEqual(x, Decimal('8.71E+799'))
2407
2408    def test_complex(self):
2409        Decimal = self.decimal.Decimal
2410
2411        x = Decimal("9.8182731e181273")
2412        self.assertEqual(x.real, x)
2413        self.assertEqual(x.imag, 0)
2414        self.assertEqual(x.conjugate(), x)
2415
2416        x = Decimal("1")
2417        self.assertEqual(complex(x), complex(float(1)))
2418
2419        self.assertRaises(AttributeError, setattr, x, 'real', 100)
2420        self.assertRaises(AttributeError, setattr, x, 'imag', 100)
2421        self.assertRaises(AttributeError, setattr, x, 'conjugate', 100)
2422        self.assertRaises(AttributeError, setattr, x, '__complex__', 100)
2423
2424class CPythonAPItests(PythonAPItests):
2425    decimal = C
2426class PyPythonAPItests(PythonAPItests):
2427    decimal = P
2428
2429class ContextAPItests(unittest.TestCase):
2430
2431    def test_pickle(self):
2432        Context = self.decimal.Context
2433
2434        c = Context()
2435        e = pickle.loads(pickle.dumps(c))
2436        if self.decimal == C:
2437            self.assertEqual(c.prec, e.prec)
2438            self.assertEqual(c.Emin, e.Emin)
2439            self.assertEqual(c.Emax, e.Emax)
2440            self.assertEqual(c.rounding, e.rounding)
2441            self.assertEqual(c.capitals, e.capitals)
2442            self.assertEqual(c.traps, e.traps)
2443            self.assertEqual(c.flags, e.flags)
2444            self.assertEqual(c._clamp, e._clamp)
2445        else:
2446            for k in vars(c):
2447                v1 = vars(c)[k]
2448                v2 = vars(e)[k]
2449                self.assertEqual(v1, v2)
2450
2451    def test_equality_with_other_types(self):
2452        Decimal = self.decimal.Decimal
2453
2454        self.assertTrue(Decimal(10) in ['a', 1.0, Decimal(10), (1,2), {}])
2455        self.assertTrue(Decimal(10) not in ['a', 1.0, (1,2), {}])
2456
2457    def test_copy(self):
2458        # All copies should be deep
2459        Decimal = self.decimal.Decimal
2460        Context = self.decimal.Context
2461
2462        c = Context()
2463        d = c.copy()
2464        self.assertNotEqual(id(c), id(d))
2465        self.assertNotEqual(id(c.flags), id(d.flags))
2466        self.assertNotEqual(id(c.traps), id(d.traps))
2467        k1 = set(c.flags.keys())
2468        k2 = set(d.flags.keys())
2469        self.assertEqual(k1, k2)
2470        self.assertEqual(c.flags, d.flags)
2471
2472    def test_abs(self):
2473        Decimal = self.decimal.Decimal
2474        Context = self.decimal.Context
2475
2476        c = Context()
2477        d = c.abs(Decimal(-1))
2478        self.assertEqual(c.abs(-1), d)
2479        self.assertRaises(TypeError, c.abs, '-1')
2480
2481    def test_add(self):
2482        Decimal = self.decimal.Decimal
2483        Context = self.decimal.Context
2484
2485        c = Context()
2486        d = c.add(Decimal(1), Decimal(1))
2487        self.assertEqual(c.add(1, 1), d)
2488        self.assertEqual(c.add(Decimal(1), 1), d)
2489        self.assertEqual(c.add(1, Decimal(1)), d)
2490        self.assertRaises(TypeError, c.add, '1', 1)
2491        self.assertRaises(TypeError, c.add, 1, '1')
2492
2493    def test_compare(self):
2494        Decimal = self.decimal.Decimal
2495        Context = self.decimal.Context
2496
2497        c = Context()
2498        d = c.compare(Decimal(1), Decimal(1))
2499        self.assertEqual(c.compare(1, 1), d)
2500        self.assertEqual(c.compare(Decimal(1), 1), d)
2501        self.assertEqual(c.compare(1, Decimal(1)), d)
2502        self.assertRaises(TypeError, c.compare, '1', 1)
2503        self.assertRaises(TypeError, c.compare, 1, '1')
2504
2505    def test_compare_signal(self):
2506        Decimal = self.decimal.Decimal
2507        Context = self.decimal.Context
2508
2509        c = Context()
2510        d = c.compare_signal(Decimal(1), Decimal(1))
2511        self.assertEqual(c.compare_signal(1, 1), d)
2512        self.assertEqual(c.compare_signal(Decimal(1), 1), d)
2513        self.assertEqual(c.compare_signal(1, Decimal(1)), d)
2514        self.assertRaises(TypeError, c.compare_signal, '1', 1)
2515        self.assertRaises(TypeError, c.compare_signal, 1, '1')
2516
2517    def test_compare_total(self):
2518        Decimal = self.decimal.Decimal
2519        Context = self.decimal.Context
2520
2521        c = Context()
2522        d = c.compare_total(Decimal(1), Decimal(1))
2523        self.assertEqual(c.compare_total(1, 1), d)
2524        self.assertEqual(c.compare_total(Decimal(1), 1), d)
2525        self.assertEqual(c.compare_total(1, Decimal(1)), d)
2526        self.assertRaises(TypeError, c.compare_total, '1', 1)
2527        self.assertRaises(TypeError, c.compare_total, 1, '1')
2528
2529    def test_compare_total_mag(self):
2530        Decimal = self.decimal.Decimal
2531        Context = self.decimal.Context
2532
2533        c = Context()
2534        d = c.compare_total_mag(Decimal(1), Decimal(1))
2535        self.assertEqual(c.compare_total_mag(1, 1), d)
2536        self.assertEqual(c.compare_total_mag(Decimal(1), 1), d)
2537        self.assertEqual(c.compare_total_mag(1, Decimal(1)), d)
2538        self.assertRaises(TypeError, c.compare_total_mag, '1', 1)
2539        self.assertRaises(TypeError, c.compare_total_mag, 1, '1')
2540
2541    def test_copy_abs(self):
2542        Decimal = self.decimal.Decimal
2543        Context = self.decimal.Context
2544
2545        c = Context()
2546        d = c.copy_abs(Decimal(-1))
2547        self.assertEqual(c.copy_abs(-1), d)
2548        self.assertRaises(TypeError, c.copy_abs, '-1')
2549
2550    def test_copy_decimal(self):
2551        Decimal = self.decimal.Decimal
2552        Context = self.decimal.Context
2553
2554        c = Context()
2555        d = c.copy_decimal(Decimal(-1))
2556        self.assertEqual(c.copy_decimal(-1), d)
2557        self.assertRaises(TypeError, c.copy_decimal, '-1')
2558
2559    def test_copy_negate(self):
2560        Decimal = self.decimal.Decimal
2561        Context = self.decimal.Context
2562
2563        c = Context()
2564        d = c.copy_negate(Decimal(-1))
2565        self.assertEqual(c.copy_negate(-1), d)
2566        self.assertRaises(TypeError, c.copy_negate, '-1')
2567
2568    def test_copy_sign(self):
2569        Decimal = self.decimal.Decimal
2570        Context = self.decimal.Context
2571
2572        c = Context()
2573        d = c.copy_sign(Decimal(1), Decimal(-2))
2574        self.assertEqual(c.copy_sign(1, -2), d)
2575        self.assertEqual(c.copy_sign(Decimal(1), -2), d)
2576        self.assertEqual(c.copy_sign(1, Decimal(-2)), d)
2577        self.assertRaises(TypeError, c.copy_sign, '1', -2)
2578        self.assertRaises(TypeError, c.copy_sign, 1, '-2')
2579
2580    def test_divide(self):
2581        Decimal = self.decimal.Decimal
2582        Context = self.decimal.Context
2583
2584        c = Context()
2585        d = c.divide(Decimal(1), Decimal(2))
2586        self.assertEqual(c.divide(1, 2), d)
2587        self.assertEqual(c.divide(Decimal(1), 2), d)
2588        self.assertEqual(c.divide(1, Decimal(2)), d)
2589        self.assertRaises(TypeError, c.divide, '1', 2)
2590        self.assertRaises(TypeError, c.divide, 1, '2')
2591
2592    def test_divide_int(self):
2593        Decimal = self.decimal.Decimal
2594        Context = self.decimal.Context
2595
2596        c = Context()
2597        d = c.divide_int(Decimal(1), Decimal(2))
2598        self.assertEqual(c.divide_int(1, 2), d)
2599        self.assertEqual(c.divide_int(Decimal(1), 2), d)
2600        self.assertEqual(c.divide_int(1, Decimal(2)), d)
2601        self.assertRaises(TypeError, c.divide_int, '1', 2)
2602        self.assertRaises(TypeError, c.divide_int, 1, '2')
2603
2604    def test_divmod(self):
2605        Decimal = self.decimal.Decimal
2606        Context = self.decimal.Context
2607
2608        c = Context()
2609        d = c.divmod(Decimal(1), Decimal(2))
2610        self.assertEqual(c.divmod(1, 2), d)
2611        self.assertEqual(c.divmod(Decimal(1), 2), d)
2612        self.assertEqual(c.divmod(1, Decimal(2)), d)
2613        self.assertRaises(TypeError, c.divmod, '1', 2)
2614        self.assertRaises(TypeError, c.divmod, 1, '2')
2615
2616    def test_exp(self):
2617        Decimal = self.decimal.Decimal
2618        Context = self.decimal.Context
2619
2620        c = Context()
2621        d = c.exp(Decimal(10))
2622        self.assertEqual(c.exp(10), d)
2623        self.assertRaises(TypeError, c.exp, '10')
2624
2625    def test_fma(self):
2626        Decimal = self.decimal.Decimal
2627        Context = self.decimal.Context
2628
2629        c = Context()
2630        d = c.fma(Decimal(2), Decimal(3), Decimal(4))
2631        self.assertEqual(c.fma(2, 3, 4), d)
2632        self.assertEqual(c.fma(Decimal(2), 3, 4), d)
2633        self.assertEqual(c.fma(2, Decimal(3), 4), d)
2634        self.assertEqual(c.fma(2, 3, Decimal(4)), d)
2635        self.assertEqual(c.fma(Decimal(2), Decimal(3), 4), d)
2636        self.assertRaises(TypeError, c.fma, '2', 3, 4)
2637        self.assertRaises(TypeError, c.fma, 2, '3', 4)
2638        self.assertRaises(TypeError, c.fma, 2, 3, '4')
2639
2640        if self.decimal == C or py_minor >= 8:
2641            # Issue 12079 for Context.fma ...
2642            self.assertRaises(TypeError, c.fma,
2643                              Decimal('Infinity'), Decimal(0), "not a decimal")
2644            self.assertRaises(TypeError, c.fma,
2645                              Decimal(1), Decimal('snan'), 1.222)
2646            # ... and for Decimal.fma.
2647            self.assertRaises(TypeError, Decimal('Infinity').fma,
2648                              Decimal(0), "not a decimal")
2649            self.assertRaises(TypeError, Decimal(1).fma,
2650                              Decimal('snan'), 1.222)
2651
2652    def test_is_finite(self):
2653        Decimal = self.decimal.Decimal
2654        Context = self.decimal.Context
2655
2656        c = Context()
2657        d = c.is_finite(Decimal(10))
2658        self.assertEqual(c.is_finite(10), d)
2659        self.assertRaises(TypeError, c.is_finite, '10')
2660
2661    def test_is_infinite(self):
2662        Decimal = self.decimal.Decimal
2663        Context = self.decimal.Context
2664
2665        c = Context()
2666        d = c.is_infinite(Decimal(10))
2667        self.assertEqual(c.is_infinite(10), d)
2668        self.assertRaises(TypeError, c.is_infinite, '10')
2669
2670    def test_is_nan(self):
2671        Decimal = self.decimal.Decimal
2672        Context = self.decimal.Context
2673
2674        c = Context()
2675        d = c.is_nan(Decimal(10))
2676        self.assertEqual(c.is_nan(10), d)
2677        self.assertRaises(TypeError, c.is_nan, '10')
2678
2679    def test_is_normal(self):
2680        Decimal = self.decimal.Decimal
2681        Context = self.decimal.Context
2682
2683        c = Context()
2684        d = c.is_normal(Decimal(10))
2685        self.assertEqual(c.is_normal(10), d)
2686        self.assertRaises(TypeError, c.is_normal, '10')
2687
2688    def test_is_qnan(self):
2689        Decimal = self.decimal.Decimal
2690        Context = self.decimal.Context
2691
2692        c = Context()
2693        d = c.is_qnan(Decimal(10))
2694        self.assertEqual(c.is_qnan(10), d)
2695        self.assertRaises(TypeError, c.is_qnan, '10')
2696
2697    def test_is_signed(self):
2698        Decimal = self.decimal.Decimal
2699        Context = self.decimal.Context
2700
2701        c = Context()
2702        d = c.is_signed(Decimal(10))
2703        self.assertEqual(c.is_signed(10), d)
2704        self.assertRaises(TypeError, c.is_signed, '10')
2705
2706    def test_is_snan(self):
2707        Decimal = self.decimal.Decimal
2708        Context = self.decimal.Context
2709
2710        c = Context()
2711        d = c.is_snan(Decimal(10))
2712        self.assertEqual(c.is_snan(10), d)
2713        self.assertRaises(TypeError, c.is_snan, '10')
2714
2715    def test_is_subnormal(self):
2716        Decimal = self.decimal.Decimal
2717        Context = self.decimal.Context
2718
2719        c = Context()
2720        d = c.is_subnormal(Decimal(10))
2721        self.assertEqual(c.is_subnormal(10), d)
2722        self.assertRaises(TypeError, c.is_subnormal, '10')
2723
2724    def test_is_zero(self):
2725        Decimal = self.decimal.Decimal
2726        Context = self.decimal.Context
2727
2728        c = Context()
2729        d = c.is_zero(Decimal(10))
2730        self.assertEqual(c.is_zero(10), d)
2731        self.assertRaises(TypeError, c.is_zero, '10')
2732
2733    def test_ln(self):
2734        Decimal = self.decimal.Decimal
2735        Context = self.decimal.Context
2736
2737        c = Context()
2738        d = c.ln(Decimal(10))
2739        self.assertEqual(c.ln(10), d)
2740        self.assertRaises(TypeError, c.ln, '10')
2741
2742    def test_log10(self):
2743        Decimal = self.decimal.Decimal
2744        Context = self.decimal.Context
2745
2746        c = Context()
2747        d = c.log10(Decimal(10))
2748        self.assertEqual(c.log10(10), d)
2749        self.assertRaises(TypeError, c.log10, '10')
2750
2751    def test_logb(self):
2752        Decimal = self.decimal.Decimal
2753        Context = self.decimal.Context
2754
2755        c = Context()
2756        d = c.logb(Decimal(10))
2757        self.assertEqual(c.logb(10), d)
2758        self.assertRaises(TypeError, c.logb, '10')
2759
2760    def test_logical_and(self):
2761        Decimal = self.decimal.Decimal
2762        Context = self.decimal.Context
2763
2764        c = Context()
2765        d = c.logical_and(Decimal(1), Decimal(1))
2766        self.assertEqual(c.logical_and(1, 1), d)
2767        self.assertEqual(c.logical_and(Decimal(1), 1), d)
2768        self.assertEqual(c.logical_and(1, Decimal(1)), d)
2769        self.assertRaises(TypeError, c.logical_and, '1', 1)
2770        self.assertRaises(TypeError, c.logical_and, 1, '1')
2771
2772    def test_logical_invert(self):
2773        Decimal = self.decimal.Decimal
2774        Context = self.decimal.Context
2775
2776        c = Context()
2777        d = c.logical_invert(Decimal(1000))
2778        self.assertEqual(c.logical_invert(1000), d)
2779        self.assertRaises(TypeError, c.logical_invert, '1000')
2780
2781    def test_logical_or(self):
2782        Decimal = self.decimal.Decimal
2783        Context = self.decimal.Context
2784
2785        c = Context()
2786        d = c.logical_or(Decimal(1), Decimal(1))
2787        self.assertEqual(c.logical_or(1, 1), d)
2788        self.assertEqual(c.logical_or(Decimal(1), 1), d)
2789        self.assertEqual(c.logical_or(1, Decimal(1)), d)
2790        self.assertRaises(TypeError, c.logical_or, '1', 1)
2791        self.assertRaises(TypeError, c.logical_or, 1, '1')
2792
2793    def test_logical_xor(self):
2794        Decimal = self.decimal.Decimal
2795        Context = self.decimal.Context
2796
2797        c = Context()
2798        d = c.logical_xor(Decimal(1), Decimal(1))
2799        self.assertEqual(c.logical_xor(1, 1), d)
2800        self.assertEqual(c.logical_xor(Decimal(1), 1), d)
2801        self.assertEqual(c.logical_xor(1, Decimal(1)), d)
2802        self.assertRaises(TypeError, c.logical_xor, '1', 1)
2803        self.assertRaises(TypeError, c.logical_xor, 1, '1')
2804
2805    def test_max(self):
2806        Decimal = self.decimal.Decimal
2807        Context = self.decimal.Context
2808
2809        c = Context()
2810        d = c.max(Decimal(1), Decimal(2))
2811        self.assertEqual(c.max(1, 2), d)
2812        self.assertEqual(c.max(Decimal(1), 2), d)
2813        self.assertEqual(c.max(1, Decimal(2)), d)
2814        self.assertRaises(TypeError, c.max, '1', 2)
2815        self.assertRaises(TypeError, c.max, 1, '2')
2816
2817    def test_max_mag(self):
2818        Decimal = self.decimal.Decimal
2819        Context = self.decimal.Context
2820
2821        c = Context()
2822        d = c.max_mag(Decimal(1), Decimal(2))
2823        self.assertEqual(c.max_mag(1, 2), d)
2824        self.assertEqual(c.max_mag(Decimal(1), 2), d)
2825        self.assertEqual(c.max_mag(1, Decimal(2)), d)
2826        self.assertRaises(TypeError, c.max_mag, '1', 2)
2827        self.assertRaises(TypeError, c.max_mag, 1, '2')
2828
2829    def test_min(self):
2830        Decimal = self.decimal.Decimal
2831        Context = self.decimal.Context
2832
2833        c = Context()
2834        d = c.min(Decimal(1), Decimal(2))
2835        self.assertEqual(c.min(1, 2), d)
2836        self.assertEqual(c.min(Decimal(1), 2), d)
2837        self.assertEqual(c.min(1, Decimal(2)), d)
2838        self.assertRaises(TypeError, c.min, '1', 2)
2839        self.assertRaises(TypeError, c.min, 1, '2')
2840
2841    def test_min_mag(self):
2842        Decimal = self.decimal.Decimal
2843        Context = self.decimal.Context
2844
2845        c = Context()
2846        d = c.min_mag(Decimal(1), Decimal(2))
2847        self.assertEqual(c.min_mag(1, 2), d)
2848        self.assertEqual(c.min_mag(Decimal(1), 2), d)
2849        self.assertEqual(c.min_mag(1, Decimal(2)), d)
2850        self.assertRaises(TypeError, c.min_mag, '1', 2)
2851        self.assertRaises(TypeError, c.min_mag, 1, '2')
2852
2853    def test_minus(self):
2854        Decimal = self.decimal.Decimal
2855        Context = self.decimal.Context
2856
2857        c = Context()
2858        d = c.minus(Decimal(10))
2859        self.assertEqual(c.minus(10), d)
2860        self.assertRaises(TypeError, c.minus, '10')
2861
2862    def test_multiply(self):
2863        Decimal = self.decimal.Decimal
2864        Context = self.decimal.Context
2865
2866        c = Context()
2867        d = c.multiply(Decimal(1), Decimal(2))
2868        self.assertEqual(c.multiply(1, 2), d)
2869        self.assertEqual(c.multiply(Decimal(1), 2), d)
2870        self.assertEqual(c.multiply(1, Decimal(2)), d)
2871        self.assertRaises(TypeError, c.multiply, '1', 2)
2872        self.assertRaises(TypeError, c.multiply, 1, '2')
2873
2874    def test_next_minus(self):
2875        Decimal = self.decimal.Decimal
2876        Context = self.decimal.Context
2877
2878        c = Context()
2879        d = c.next_minus(Decimal(10))
2880        self.assertEqual(c.next_minus(10), d)
2881        self.assertRaises(TypeError, c.next_minus, '10')
2882
2883    def test_next_plus(self):
2884        Decimal = self.decimal.Decimal
2885        Context = self.decimal.Context
2886
2887        c = Context()
2888        d = c.next_plus(Decimal(10))
2889        self.assertEqual(c.next_plus(10), d)
2890        self.assertRaises(TypeError, c.next_plus, '10')
2891
2892    def test_next_toward(self):
2893        Decimal = self.decimal.Decimal
2894        Context = self.decimal.Context
2895
2896        c = Context()
2897        d = c.next_toward(Decimal(1), Decimal(2))
2898        self.assertEqual(c.next_toward(1, 2), d)
2899        self.assertEqual(c.next_toward(Decimal(1), 2), d)
2900        self.assertEqual(c.next_toward(1, Decimal(2)), d)
2901        self.assertRaises(TypeError, c.next_toward, '1', 2)
2902        self.assertRaises(TypeError, c.next_toward, 1, '2')
2903
2904    def test_normalize(self):
2905        Decimal = self.decimal.Decimal
2906        Context = self.decimal.Context
2907
2908        c = Context()
2909        d = c.normalize(Decimal(10))
2910        self.assertEqual(c.normalize(10), d)
2911        self.assertRaises(TypeError, c.normalize, '10')
2912
2913    def test_number_class(self):
2914        Decimal = self.decimal.Decimal
2915        Context = self.decimal.Context
2916
2917        c = Context()
2918        self.assertEqual(c.number_class(123), c.number_class(Decimal(123)))
2919        self.assertEqual(c.number_class(0), c.number_class(Decimal(0)))
2920        self.assertEqual(c.number_class(-45), c.number_class(Decimal(-45)))
2921
2922    def test_plus(self):
2923        Decimal = self.decimal.Decimal
2924        Context = self.decimal.Context
2925
2926        c = Context()
2927        d = c.plus(Decimal(10))
2928        self.assertEqual(c.plus(10), d)
2929        self.assertRaises(TypeError, c.plus, '10')
2930
2931    def test_power(self):
2932        Decimal = self.decimal.Decimal
2933        Context = self.decimal.Context
2934
2935        c = Context()
2936        d = c.power(Decimal(1), Decimal(4))
2937        self.assertEqual(c.power(1, 4), d)
2938        self.assertEqual(c.power(Decimal(1), 4), d)
2939        self.assertEqual(c.power(1, Decimal(4)), d)
2940        self.assertEqual(c.power(Decimal(1), Decimal(4)), d)
2941        self.assertRaises(TypeError, c.power, '1', 4)
2942        self.assertRaises(TypeError, c.power, 1, '4')
2943
2944    def test_quantize(self):
2945        Decimal = self.decimal.Decimal
2946        Context = self.decimal.Context
2947
2948        c = Context()
2949        d = c.quantize(Decimal(1), Decimal(2))
2950        self.assertEqual(c.quantize(1, 2), d)
2951        self.assertEqual(c.quantize(Decimal(1), 2), d)
2952        self.assertEqual(c.quantize(1, Decimal(2)), d)
2953        self.assertRaises(TypeError, c.quantize, '1', 2)
2954        self.assertRaises(TypeError, c.quantize, 1, '2')
2955
2956    def test_remainder(self):
2957        Decimal = self.decimal.Decimal
2958        Context = self.decimal.Context
2959
2960        c = Context()
2961        d = c.remainder(Decimal(1), Decimal(2))
2962        self.assertEqual(c.remainder(1, 2), d)
2963        self.assertEqual(c.remainder(Decimal(1), 2), d)
2964        self.assertEqual(c.remainder(1, Decimal(2)), d)
2965        self.assertRaises(TypeError, c.remainder, '1', 2)
2966        self.assertRaises(TypeError, c.remainder, 1, '2')
2967
2968    def test_remainder_near(self):
2969        Decimal = self.decimal.Decimal
2970        Context = self.decimal.Context
2971
2972        c = Context()
2973        d = c.remainder_near(Decimal(1), Decimal(2))
2974        self.assertEqual(c.remainder_near(1, 2), d)
2975        self.assertEqual(c.remainder_near(Decimal(1), 2), d)
2976        self.assertEqual(c.remainder_near(1, Decimal(2)), d)
2977        self.assertRaises(TypeError, c.remainder_near, '1', 2)
2978        self.assertRaises(TypeError, c.remainder_near, 1, '2')
2979
2980    def test_rotate(self):
2981        Decimal = self.decimal.Decimal
2982        Context = self.decimal.Context
2983
2984        c = Context()
2985        d = c.rotate(Decimal(1), Decimal(2))
2986        self.assertEqual(c.rotate(1, 2), d)
2987        self.assertEqual(c.rotate(Decimal(1), 2), d)
2988        self.assertEqual(c.rotate(1, Decimal(2)), d)
2989        self.assertRaises(TypeError, c.rotate, '1', 2)
2990        self.assertRaises(TypeError, c.rotate, 1, '2')
2991
2992    def test_sqrt(self):
2993        Decimal = self.decimal.Decimal
2994        Context = self.decimal.Context
2995
2996        c = Context()
2997        d = c.sqrt(Decimal(10))
2998        self.assertEqual(c.sqrt(10), d)
2999        self.assertRaises(TypeError, c.sqrt, '10')
3000
3001    def test_same_quantum(self):
3002        Decimal = self.decimal.Decimal
3003        Context = self.decimal.Context
3004
3005        c = Context()
3006        d = c.same_quantum(Decimal(1), Decimal(2))
3007        self.assertEqual(c.same_quantum(1, 2), d)
3008        self.assertEqual(c.same_quantum(Decimal(1), 2), d)
3009        self.assertEqual(c.same_quantum(1, Decimal(2)), d)
3010        self.assertRaises(TypeError, c.same_quantum, '1', 2)
3011        self.assertRaises(TypeError, c.same_quantum, 1, '2')
3012
3013    def test_scaleb(self):
3014        Decimal = self.decimal.Decimal
3015        Context = self.decimal.Context
3016
3017        c = Context()
3018        d = c.scaleb(Decimal(1), Decimal(2))
3019        self.assertEqual(c.scaleb(1, 2), d)
3020        self.assertEqual(c.scaleb(Decimal(1), 2), d)
3021        self.assertEqual(c.scaleb(1, Decimal(2)), d)
3022        self.assertRaises(TypeError, c.scaleb, '1', 2)
3023        self.assertRaises(TypeError, c.scaleb, 1, '2')
3024
3025    def test_shift(self):
3026        Decimal = self.decimal.Decimal
3027        Context = self.decimal.Context
3028
3029        c = Context()
3030        d = c.shift(Decimal(1), Decimal(2))
3031        self.assertEqual(c.shift(1, 2), d)
3032        self.assertEqual(c.shift(Decimal(1), 2), d)
3033        self.assertEqual(c.shift(1, Decimal(2)), d)
3034        self.assertRaises(TypeError, c.shift, '1', 2)
3035        self.assertRaises(TypeError, c.shift, 1, '2')
3036
3037    def test_subtract(self):
3038        Decimal = self.decimal.Decimal
3039        Context = self.decimal.Context
3040
3041        c = Context()
3042        d = c.subtract(Decimal(1), Decimal(2))
3043        self.assertEqual(c.subtract(1, 2), d)
3044        self.assertEqual(c.subtract(Decimal(1), 2), d)
3045        self.assertEqual(c.subtract(1, Decimal(2)), d)
3046        self.assertRaises(TypeError, c.subtract, '1', 2)
3047        self.assertRaises(TypeError, c.subtract, 1, '2')
3048
3049    def test_to_eng_string(self):
3050        Decimal = self.decimal.Decimal
3051        Context = self.decimal.Context
3052
3053        c = Context()
3054        d = c.to_eng_string(Decimal(10))
3055        self.assertEqual(c.to_eng_string(10), d)
3056        self.assertRaises(TypeError, c.to_eng_string, '10')
3057
3058    def test_to_sci_string(self):
3059        Decimal = self.decimal.Decimal
3060        Context = self.decimal.Context
3061
3062        c = Context()
3063        d = c.to_sci_string(Decimal(10))
3064        self.assertEqual(c.to_sci_string(10), d)
3065        self.assertRaises(TypeError, c.to_sci_string, '10')
3066
3067    def test_to_integral_exact(self):
3068        Decimal = self.decimal.Decimal
3069        Context = self.decimal.Context
3070
3071        c = Context()
3072        d = c.to_integral_exact(Decimal(10))
3073        self.assertEqual(c.to_integral_exact(10), d)
3074        self.assertRaises(TypeError, c.to_integral_exact, '10')
3075
3076    def test_to_integral_value(self):
3077        Decimal = self.decimal.Decimal
3078        Context = self.decimal.Context
3079
3080        c = Context()
3081        d = c.to_integral_value(Decimal(10))
3082        self.assertEqual(c.to_integral_value(10), d)
3083        self.assertRaises(TypeError, c.to_integral_value, '10')
3084        self.assertRaises(TypeError, c.to_integral_value, 10, 'x')
3085
3086class CContextAPItests(ContextAPItests):
3087    decimal = C
3088if py_minor >= 7:
3089    class PyContextAPItests(ContextAPItests):
3090        decimal = P
3091else:
3092    class PyContextAPItests(unittest.TestCase):
3093        pass
3094
3095class ContextWithStatement(unittest.TestCase):
3096    # Can't do these as docstrings until Python 2.6
3097    # as doctest can't handle __future__ statements
3098
3099    def test_localcontext(self):
3100        # Use a copy of the current context in the block
3101        getcontext = self.decimal.getcontext
3102        localcontext = self.decimal.localcontext
3103
3104        orig_ctx = getcontext()
3105        with localcontext() as enter_ctx:
3106            set_ctx = getcontext()
3107        final_ctx = getcontext()
3108        self.assertTrue(orig_ctx is final_ctx, 'did not restore context correctly')
3109        self.assertTrue(orig_ctx is not set_ctx, 'did not copy the context')
3110        self.assertTrue(set_ctx is enter_ctx, '__enter__ returned wrong context')
3111
3112    def test_localcontextarg(self):
3113        # Use a copy of the supplied context in the block
3114        Context = self.decimal.Context
3115        getcontext = self.decimal.getcontext
3116        localcontext = self.decimal.localcontext
3117
3118        localcontext = self.decimal.localcontext
3119        orig_ctx = getcontext()
3120        new_ctx = Context(prec=42)
3121        with localcontext(new_ctx) as enter_ctx:
3122            set_ctx = getcontext()
3123        final_ctx = getcontext()
3124        self.assertTrue(orig_ctx is final_ctx, 'did not restore context correctly')
3125        self.assertTrue(set_ctx.prec == new_ctx.prec, 'did not set correct context')
3126        self.assertTrue(new_ctx is not set_ctx, 'did not copy the context')
3127        self.assertTrue(set_ctx is enter_ctx, '__enter__ returned wrong context')
3128
3129    def test_nested_with_statements(self):
3130        # Use a copy of the supplied context in the block
3131        Decimal = self.decimal.Decimal
3132        Context = self.decimal.Context
3133        getcontext = self.decimal.getcontext
3134        localcontext = self.decimal.localcontext
3135        Clamped = self.decimal.Clamped
3136        Overflow = self.decimal.Overflow
3137
3138        orig_ctx = getcontext()
3139        orig_ctx.clear_flags()
3140        new_ctx = Context(Emax=384)
3141        with localcontext() as c1:
3142            self.assertEqual(c1.flags, orig_ctx.flags)
3143            self.assertEqual(c1.traps, orig_ctx.traps)
3144            c1.traps[Clamped] = True
3145            c1.Emin = -383
3146            self.assertNotEqual(orig_ctx.Emin, -383)
3147            self.assertRaises(Clamped, c1.create_decimal, '0e-999')
3148            self.assertTrue(c1.flags[Clamped])
3149            with localcontext(new_ctx) as c2:
3150                self.assertEqual(c2.flags, new_ctx.flags)
3151                self.assertEqual(c2.traps, new_ctx.traps)
3152                self.assertRaises(Overflow, c2.power, Decimal('3.4e200'), 2)
3153                self.assertFalse(c2.flags[Clamped])
3154                self.assertTrue(c2.flags[Overflow])
3155                del c2
3156            self.assertFalse(c1.flags[Overflow])
3157            del c1
3158        self.assertNotEqual(orig_ctx.Emin, -383)
3159        self.assertFalse(orig_ctx.flags[Clamped])
3160        self.assertFalse(orig_ctx.flags[Overflow])
3161        self.assertFalse(new_ctx.flags[Clamped])
3162        self.assertFalse(new_ctx.flags[Overflow])
3163
3164    def test_with_statements_gc1(self):
3165        localcontext = self.decimal.localcontext
3166
3167        with localcontext() as c1:
3168            del c1
3169            with localcontext() as c2:
3170                del c2
3171                with localcontext() as c3:
3172                    del c3
3173                    with localcontext() as c4:
3174                        del c4
3175
3176    def test_with_statements_gc2(self):
3177        localcontext = self.decimal.localcontext
3178
3179        with localcontext() as c1:
3180            with localcontext(c1) as c2:
3181                del c1
3182                with localcontext(c2) as c3:
3183                    del c2
3184                    with localcontext(c3) as c4:
3185                        del c3
3186                        del c4
3187
3188    def test_with_statements_gc3(self):
3189        Context = self.decimal.Context
3190        localcontext = self.decimal.localcontext
3191        getcontext = self.decimal.getcontext
3192        setcontext = self.decimal.setcontext
3193
3194        with localcontext() as c1:
3195            del c1
3196            n1 = Context(prec=1)
3197            setcontext(n1)
3198            with localcontext(n1) as c2:
3199                del n1
3200                self.assertEqual(c2.prec, 1)
3201                del c2
3202                n2 = Context(prec=2)
3203                setcontext(n2)
3204                del n2
3205                self.assertEqual(getcontext().prec, 2)
3206                n3 = Context(prec=3)
3207                setcontext(n3)
3208                self.assertEqual(getcontext().prec, 3)
3209                with localcontext(n3) as c3:
3210                    del n3
3211                    self.assertEqual(c3.prec, 3)
3212                    del c3
3213                    n4 = Context(prec=4)
3214                    setcontext(n4)
3215                    del n4
3216                    self.assertEqual(getcontext().prec, 4)
3217                    with localcontext() as c4:
3218                        self.assertEqual(c4.prec, 4)
3219                        del c4
3220
3221class CContextWithStatement(ContextWithStatement):
3222    decimal = C
3223class PyContextWithStatement(ContextWithStatement):
3224    decimal = P
3225
3226class ContextFlags(unittest.TestCase):
3227    def test_flags_irrelevant(self):
3228        # check that the result (numeric result + flags raised) of an
3229        # arithmetic operation doesn't depend on the current flags
3230        Decimal = self.decimal.Decimal
3231        Context = self.decimal.Context
3232        Inexact = self.decimal.Inexact
3233        Rounded = self.decimal.Rounded
3234        Underflow = self.decimal.Underflow
3235        Clamped = self.decimal.Clamped
3236        Subnormal = self.decimal.Subnormal
3237        ROUND_HALF_EVEN = self.decimal.ROUND_HALF_EVEN
3238
3239        def raise_error(context, flag):
3240            if self.decimal == C:
3241                context.flags[flag] = True
3242                if context.traps[flag]:
3243                    raise flag
3244            else:
3245                context._raise_error(flag)
3246
3247        context = Context(prec=9, Emin = -425000000, Emax = 425000000,
3248                          rounding=ROUND_HALF_EVEN, traps=[], flags=[])
3249
3250        # operations that raise various flags, in the form (function, arglist)
3251        operations = [
3252            (context._apply, [Decimal("100E-425000010")]),
3253            (context.sqrt, [Decimal(2)]),
3254            (context.add, [Decimal("1.23456789"), Decimal("9.87654321")]),
3255            (context.multiply, [Decimal("1.23456789"), Decimal("9.87654321")]),
3256            (context.subtract, [Decimal("1.23456789"), Decimal("9.87654321")]),
3257            ]
3258
3259        # try various flags individually, then a whole lot at once
3260        flagsets = [[Inexact], [Rounded], [Underflow], [Clamped], [Subnormal],
3261                    [Inexact, Rounded, Underflow, Clamped, Subnormal]]
3262
3263        for fn, args in operations:
3264            # find answer and flags raised using a clean context
3265            context.clear_flags()
3266            ans = fn(*args)
3267            flags = [k for k, v in context.flags.items() if v]
3268
3269            for extra_flags in flagsets:
3270                # set flags, before calling operation
3271                context.clear_flags()
3272                for flag in extra_flags:
3273                    raise_error(context, flag)
3274                new_ans = fn(*args)
3275
3276                # flags that we expect to be set after the operation
3277                expected_flags = list(flags)
3278                for flag in extra_flags:
3279                    if flag not in expected_flags:
3280                        expected_flags.append(flag)
3281                expected_flags.sort(key=id)
3282
3283                # flags we actually got
3284                new_flags = [k for k,v in context.flags.items() if v]
3285                new_flags.sort(key=id)
3286
3287                self.assertEqual(ans, new_ans,
3288                                 "operation produces different answers depending on flags set: " +
3289                                 "expected %s, got %s." % (ans, new_ans))
3290                self.assertEqual(new_flags, expected_flags,
3291                                  "operation raises different flags depending on flags set: " +
3292                                  "expected %s, got %s" % (expected_flags, new_flags))
3293
3294class CContextFlags(ContextFlags):
3295    decimal = C
3296class PyContextFlags(ContextFlags):
3297    decimal = P
3298
3299class SpecialContexts(unittest.TestCase):
3300    """Test the context templates."""
3301
3302    def test_context_templates(self):
3303        BasicContext = self.decimal.BasicContext
3304        ExtendedContext = self.decimal.ExtendedContext
3305        getcontext = self.decimal.getcontext
3306        setcontext = self.decimal.setcontext
3307        InvalidOperation = self.decimal.InvalidOperation
3308        DivisionByZero = self.decimal.DivisionByZero
3309        Overflow = self.decimal.Overflow
3310        Underflow = self.decimal.Underflow
3311        Clamped = self.decimal.Clamped
3312
3313        assert_signals(self, BasicContext, 'traps',
3314            [InvalidOperation, DivisionByZero, Overflow, Underflow, Clamped]
3315        )
3316
3317        savecontext = getcontext().copy()
3318        basic_context_prec = BasicContext.prec
3319        extended_context_prec = ExtendedContext.prec
3320
3321        ex = None
3322        try:
3323            BasicContext.prec = ExtendedContext.prec = 441
3324            for template in BasicContext, ExtendedContext:
3325                setcontext(template)
3326                c = getcontext()
3327                self.assertFalse(c is template)
3328                self.assertEqual(c.prec, 441)
3329        except Exception as e:
3330            ex = e.__class__
3331        finally:
3332            with protectfail():
3333                BasicContext.prec = basic_context_prec
3334                ExtendedContext.prec = extended_context_prec
3335                setcontext(savecontext)
3336            if ex:
3337                raise ex
3338
3339    def test_default_context(self):
3340        DefaultContext = self.decimal.DefaultContext
3341        BasicContext = self.decimal.BasicContext
3342        ExtendedContext = self.decimal.ExtendedContext
3343        getcontext = self.decimal.getcontext
3344        setcontext = self.decimal.setcontext
3345        InvalidOperation = self.decimal.InvalidOperation
3346        DivisionByZero = self.decimal.DivisionByZero
3347        Overflow = self.decimal.Overflow
3348
3349        self.assertEqual(BasicContext.prec, 9)
3350        self.assertEqual(ExtendedContext.prec, 9)
3351
3352        assert_signals(self, DefaultContext, 'traps',
3353            [InvalidOperation, DivisionByZero, Overflow]
3354        )
3355
3356        savecontext = getcontext().copy()
3357        default_context_prec = DefaultContext.prec
3358
3359        ex = None
3360        try:
3361            c = getcontext()
3362            saveprec = c.prec
3363
3364            DefaultContext.prec = 961
3365            c = getcontext()
3366            self.assertEqual(c.prec, saveprec)
3367
3368            setcontext(DefaultContext)
3369            c = getcontext()
3370            self.assertFalse(c is DefaultContext)
3371            self.assertEqual(c.prec, 961)
3372        except Exception as e:
3373            ex = e.__class__
3374        finally:
3375            with protectfail():
3376                DefaultContext.prec = default_context_prec
3377                setcontext(savecontext)
3378            if ex:
3379                raise ex
3380
3381class CSpecialContexts(SpecialContexts):
3382    decimal = C
3383class PySpecialContexts(SpecialContexts):
3384    decimal = P
3385
3386class ContextInputValidation(unittest.TestCase):
3387
3388    def test_invalid_context(self):
3389        Context = self.decimal.Context
3390        DefaultContext = self.decimal.DefaultContext
3391
3392        c = DefaultContext.copy()
3393
3394        # prec, Emax
3395        for attr in ['prec', 'Emax']:
3396            setattr(c, attr, 999999)
3397            self.assertEqual(getattr(c, attr), 999999)
3398            self.assertRaises(ValueError, setattr, c, attr, -1)
3399            self.assertRaises(TypeError, setattr, c, attr, 'xyz')
3400
3401        # Emin
3402        setattr(c, 'Emin', -999999)
3403        self.assertEqual(getattr(c, 'Emin'), -999999)
3404        self.assertRaises(ValueError, setattr, c, 'Emin', 1)
3405        self.assertRaises(TypeError, setattr, c, 'Emin', (1,2,3))
3406
3407        # rounding: always raise TypeError in order to get consistent
3408        # exceptions across implementations. In decimal, rounding
3409        # modes are strings, in _decimal they are integers. The idea
3410        # is to view rounding as an abstract type and not mind the
3411        # implementation details.
3412        # Hence, a user should view the rounding modes as if they
3413        # had been defined in a language that supports abstract
3414        # data types, e.g. ocaml:
3415        #
3416        #   type rounding = ROUND_DOWN | ROUND_HALF_UP | ... ;;
3417        #
3418        self.assertRaises(TypeError, setattr, c, 'rounding', -1)
3419        self.assertRaises(TypeError, setattr, c, 'rounding', 9)
3420        self.assertRaises(TypeError, setattr, c, 'rounding', 1.0)
3421        self.assertRaises(TypeError, setattr, c, 'rounding', 'xyz')
3422
3423        # capitals, clamp
3424        for attr in ['capitals', 'clamp']:
3425            self.assertRaises(ValueError, setattr, c, attr, -1)
3426            self.assertRaises(ValueError, setattr, c, attr, 2)
3427            self.assertRaises(TypeError, setattr, c, attr, [1,2,3])
3428
3429        # Invalid attribute
3430        self.assertRaises(AttributeError, setattr, c, 'emax', 100)
3431
3432        # Invalid signal dict
3433        self.assertRaises(TypeError, setattr, c, 'flags', [])
3434        self.assertRaises(TypeError, setattr, c, 'flags', {})
3435        self.assertRaises(TypeError, setattr, c, 'traps',
3436                          {'InvalidOperation':0})
3437
3438        # Attributes cannot be deleted
3439        for attr in ['prec', 'Emax', 'Emin', 'rounding', 'capitals', 'clamp',
3440                     'flags', 'traps']:
3441            self.assertRaises(AttributeError, c.__delattr__, attr)
3442
3443        # Invalid attributes
3444        self.assertRaises(TypeError, getattr, c, 9)
3445        self.assertRaises(TypeError, setattr, c, 9)
3446
3447        # Invalid values in constructor
3448        self.assertRaises(TypeError, Context, rounding=999999)
3449        self.assertRaises(TypeError, Context, rounding='xyz')
3450        self.assertRaises(ValueError, Context, clamp=2)
3451        self.assertRaises(ValueError, Context, capitals=-1)
3452        self.assertRaises(TypeError, Context, flags=["P"])
3453        self.assertRaises(TypeError, Context, traps=["Q"])
3454
3455        # Type error in conversion
3456        self.assertRaises(TypeError, Context, flags=(0,1))
3457        self.assertRaises(TypeError, Context, traps=(1,0))
3458
3459class CContextInputValidation(ContextInputValidation):
3460    decimal = C
3461class PyContextInputValidation(unittest.TestCase):
3462    # No context input validation in decimal.py
3463    pass
3464
3465class Coverage(unittest.TestCase):
3466
3467    def test_adjusted(self):
3468        Decimal = self.decimal.Decimal
3469
3470        self.assertEqual(Decimal('1234e9999').adjusted(), 10002)
3471        # XXX raise?
3472        self.assertEqual(Decimal('nan').adjusted(), 0)
3473        self.assertEqual(Decimal('inf').adjusted(), 0)
3474
3475    def test_canonical(self):
3476        Decimal = self.decimal.Decimal
3477        getcontext = self.decimal.getcontext
3478
3479        x = Decimal(9).canonical()
3480        self.assertEqual(x, 9)
3481
3482        c = getcontext()
3483        x = c.canonical(Decimal(9))
3484        self.assertEqual(x, 9)
3485
3486    def test_context_repr(self):
3487        c = self.decimal.DefaultContext.copy()
3488
3489        if py_minor <= 8 and self.decimal == P:
3490            raise unittest.SkipTest("requires Python 3.2")
3491
3492        c.prec = 425000000
3493        c.Emax = 425000000
3494        c.Emin = -425000000
3495        c.rounding = self.decimal.ROUND_HALF_DOWN
3496        c.capitals = 0
3497        c.clamp = 1
3498        for sig in OrderedSignals[self.decimal]:
3499            c.flags[sig] = False
3500            c.traps[sig] = False
3501
3502        s = c.__repr__()
3503        t = "Context(prec=425000000, rounding=ROUND_HALF_DOWN, " \
3504            "Emin=-425000000, Emax=425000000, capitals=0, clamp=1, " \
3505            "flags=[], traps=[])"
3506        self.assertEqual(s, t)
3507
3508    def test_implicit_context(self):
3509        Decimal = self.decimal.Decimal
3510        localcontext = self.decimal.localcontext
3511
3512        with localcontext() as c:
3513            c.prec = 1
3514            c.Emax = 1
3515            c.Emin = -1
3516
3517            # abs
3518            self.assertEqual(abs(Decimal("-10")), 10)
3519            # add
3520            self.assertEqual(Decimal("7") + 1, 8)
3521            # divide
3522            self.assertEqual(Decimal("10") / 5, 2)
3523            # divide_int
3524            self.assertEqual(Decimal("10") // 7, 1)
3525            # fma
3526            self.assertEqual(Decimal("1.2").fma(Decimal("0.01"), 1), 1)
3527            self.assertTrue(Decimal("NaN").fma(7, 1).is_nan() is True)
3528            # three arg power
3529            self.assertEqual(pow(Decimal(10), 2, 7), 2)
3530            # exp
3531            self.assertEqual(Decimal("1.01").exp(), 3)
3532            # is_normal
3533            self.assertTrue(Decimal("0.01").is_normal() is False)
3534            # is_subnormal
3535            self.assertTrue(Decimal("0.01").is_subnormal() is True)
3536            # ln
3537            self.assertEqual(Decimal("20").ln(), 3)
3538            # log10
3539            self.assertEqual(Decimal("20").log10(), 1)
3540            # logb
3541            self.assertEqual(Decimal("580").logb(), 2)
3542            # logical_invert
3543            self.assertEqual(Decimal("10").logical_invert(), 1)
3544            # minus
3545            self.assertEqual(-Decimal("-10"), 10)
3546            # multiply
3547            self.assertEqual(Decimal("2") * 4, 8)
3548            # next_minus
3549            self.assertEqual(Decimal("10").next_minus(), 9)
3550            # next_plus
3551            self.assertEqual(Decimal("10").next_plus(), Decimal('2E+1'))
3552            # normalize
3553            self.assertEqual(Decimal("-10").normalize(), Decimal('-1E+1'))
3554            # number_class
3555            self.assertEqual(Decimal("10").number_class(), '+Normal')
3556            # plus
3557            self.assertEqual(+Decimal("-1"), -1)
3558            # remainder
3559            self.assertEqual(Decimal("10") % 7, 3)
3560            # subtract
3561            self.assertEqual(Decimal("10") - 7, 3)
3562            # to_integral_exact
3563            self.assertEqual(Decimal("1.12345").to_integral_exact(), 1)
3564
3565            # Boolean functions
3566            self.assertTrue(Decimal("1").is_canonical())
3567            self.assertTrue(Decimal("1").is_finite())
3568            self.assertTrue(Decimal("1").is_finite())
3569            self.assertTrue(Decimal("snan").is_snan())
3570            self.assertTrue(Decimal("-1").is_signed())
3571            self.assertTrue(Decimal("0").is_zero())
3572            self.assertTrue(Decimal("0").is_zero())
3573
3574        # Copy
3575        with localcontext() as c:
3576            c.prec = 10000
3577            x = 1228 ** 1523
3578            y = -Decimal(x)
3579
3580            z = y.copy_abs()
3581            self.assertEqual(z, x)
3582
3583            z = y.copy_negate()
3584            self.assertEqual(z, x)
3585
3586            z = y.copy_sign(Decimal(1))
3587            self.assertEqual(z, x)
3588
3589    def test_divmod(self):
3590        Decimal = self.decimal.Decimal
3591        localcontext = self.decimal.localcontext
3592        InvalidOperation = self.decimal.InvalidOperation
3593        DivisionByZero = self.decimal.DivisionByZero
3594
3595        with localcontext() as c:
3596            q, r = divmod(Decimal("10912837129"), 1001)
3597            self.assertEqual(q, Decimal('10901935'))
3598            self.assertEqual(r, Decimal('194'))
3599
3600            q, r = divmod(Decimal("NaN"), 7)
3601            self.assertTrue(q.is_nan() and r.is_nan())
3602
3603            c.traps[InvalidOperation] = False
3604            q, r = divmod(Decimal("NaN"), 7)
3605            self.assertTrue(q.is_nan() and r.is_nan())
3606
3607            c.traps[InvalidOperation] = False
3608            c.clear_flags()
3609            q, r = divmod(Decimal("inf"), Decimal("inf"))
3610            self.assertTrue(q.is_nan() and r.is_nan())
3611            self.assertTrue(c.flags[InvalidOperation])
3612
3613            c.clear_flags()
3614            q, r = divmod(Decimal("inf"), 101)
3615            self.assertTrue(q.is_infinite() and r.is_nan())
3616            self.assertTrue(c.flags[InvalidOperation])
3617
3618            c.clear_flags()
3619            q, r = divmod(Decimal(0), 0)
3620            self.assertTrue(q.is_nan() and r.is_nan())
3621            self.assertTrue(c.flags[InvalidOperation])
3622
3623            c.traps[DivisionByZero] = False
3624            c.clear_flags()
3625            q, r = divmod(Decimal(11), 0)
3626            self.assertTrue(q.is_infinite() and r.is_nan())
3627            self.assertTrue(c.flags[InvalidOperation] and
3628                            c.flags[DivisionByZero])
3629
3630    def test_power(self):
3631        Decimal = self.decimal.Decimal
3632        localcontext = self.decimal.localcontext
3633        Overflow = self.decimal.Overflow
3634        Rounded = self.decimal.Rounded
3635
3636        with localcontext() as c:
3637            c.prec = 3
3638            c.clear_flags()
3639            self.assertEqual(Decimal("1.0") ** 100, Decimal('1.00'))
3640            self.assertTrue(c.flags[Rounded])
3641
3642            c.prec = 1
3643            c.Emax = 1
3644            c.Emin = -1
3645            c.clear_flags()
3646            c.traps[Overflow] = False
3647            self.assertEqual(Decimal(10000) ** Decimal("0.5"), Decimal('inf'))
3648            self.assertTrue(c.flags[Overflow])
3649
3650    def test_quantize(self):
3651        Decimal = self.decimal.Decimal
3652        localcontext = self.decimal.localcontext
3653        InvalidOperation = self.decimal.InvalidOperation
3654
3655        with localcontext() as c:
3656            c.prec = 1
3657            c.Emax = 1
3658            c.Emin = -1
3659            c.traps[InvalidOperation] = False
3660            x = Decimal(99).quantize(Decimal("1e1"))
3661            self.assertTrue(x.is_nan())
3662
3663    def test_radix(self):
3664        Decimal = self.decimal.Decimal
3665        getcontext = self.decimal.getcontext
3666
3667        c = getcontext()
3668        self.assertEqual(Decimal("1").radix(), 10)
3669        self.assertEqual(c.radix(), 10)
3670
3671    def test_rop(self):
3672        Decimal = self.decimal.Decimal
3673
3674        for attr in ('__radd__', '__rsub__', '__rmul__', '__rtruediv__',
3675                     '__rdivmod__', '__rmod__', '__rfloordiv__', '__rpow__'):
3676            self.assertTrue(getattr(Decimal("1"), attr)("xyz") is NotImplemented)
3677
3678    def test_round(self):
3679        # Python3 behavior: round() returns Decimal
3680        Decimal = self.decimal.Decimal
3681        getcontext = self.decimal.getcontext
3682
3683        if self.decimal == P:
3684            return
3685
3686        c = getcontext()
3687        c.prec = 28
3688
3689        self.assertEqual(str(Decimal("9.99").__round__()), "10")
3690        self.assertEqual(str(Decimal("9.99e-5").__round__()), "0")
3691        self.assertEqual(str(Decimal("1.23456789").__round__(5)), "1.23457")
3692        self.assertEqual(str(Decimal("1.2345").__round__(10)), "1.2345000000")
3693        self.assertEqual(str(Decimal("1.2345").__round__(-10)), "0E+10")
3694
3695        self.assertRaises(TypeError, Decimal("1.23").__round__, "5")
3696        self.assertRaises(TypeError, Decimal("1.23").__round__, 5, 8)
3697
3698    def test_create_decimal(self):
3699        c = self.decimal.Context()
3700        self.assertRaises(ValueError, c.create_decimal, ["%"])
3701
3702    def test_int(self):
3703        Decimal = self.decimal.Decimal
3704        localcontext = self.decimal.localcontext
3705
3706        with localcontext() as c:
3707            c.prec = 9999
3708            x = Decimal(1221**1271) / 10**3923
3709            self.assertEqual(int(x), 1)
3710            self.assertEqual(x.to_integral(), 2)
3711
3712    def test_long(self):
3713        Decimal = self.decimal.Decimal
3714        DefaultContext = self.decimal.DefaultContext
3715
3716        c = DefaultContext.copy()
3717
3718        x = Decimal(28) * 28L
3719        self.assertEqual(str(x), '784')
3720
3721        x = c.multiply(Decimal(101), 101L)
3722        self.assertEqual(str(x), '10201')
3723
3724    def test_copy(self):
3725        Context = self.decimal.Context
3726
3727        if py_minor <= 1 and self.decimal == P:
3728            raise unittest.SkipTest("requires Python 3.2")
3729
3730        c = Context()
3731        c.prec = 10000
3732        x = -(1172 ** 1712)
3733
3734        y = c.copy_abs(x)
3735        self.assertEqual(y, -x)
3736
3737        y = c.copy_negate(x)
3738        self.assertEqual(y, -x)
3739
3740        y = c.copy_sign(x, 1)
3741        self.assertEqual(y, -x)
3742
3743class CCoverage(Coverage):
3744    decimal = C
3745class PyCoverage(Coverage):
3746    decimal = P
3747
3748class PyFunctionality(unittest.TestCase):
3749    """Extra functionality in decimal.py"""
3750
3751    def test_py_quantize_watchexp(self):
3752        # watchexp functionality
3753        Decimal = P.Decimal
3754        localcontext = P.localcontext
3755
3756        with localcontext() as c:
3757            c.prec = 1
3758            c.Emax = 1
3759            c.Emin = -1
3760            x = Decimal(99999).quantize(Decimal("1e3"), watchexp=False)
3761            self.assertEqual(x, Decimal('1.00E+5'))
3762
3763class PyWhitebox(unittest.TestCase):
3764    """White box testing for decimal.py"""
3765
3766    def test_py_exact_power(self):
3767        # Rarely exercised lines in _power_exact.
3768        Decimal = P.Decimal
3769        localcontext = P.localcontext
3770
3771        with localcontext() as c:
3772            c.prec = 8
3773            x = Decimal(2**16) ** Decimal("-0.5")
3774            self.assertEqual(x, Decimal('0.00390625'))
3775
3776            x = Decimal(2**16) ** Decimal("-0.6")
3777            self.assertEqual(x, Decimal('0.0012885819'))
3778
3779            x = Decimal("256e7") ** Decimal("-0.5")
3780
3781            x = Decimal(152587890625) ** Decimal('-0.0625')
3782            self.assertEqual(x, Decimal("0.2"))
3783
3784            x = Decimal("152587890625e7") ** Decimal('-0.0625')
3785
3786            x = Decimal(5**2659) ** Decimal('-0.0625')
3787
3788            c.prec = 1
3789            x = Decimal("152587890625") ** Decimal('-0.5')
3790            c.prec = 201
3791            x = Decimal(2**578) ** Decimal("-0.5")
3792
3793    def test_py_immutability_operations(self):
3794        # Do operations and check that it didn't change change internal objects.
3795        Decimal = P.Decimal
3796        DefaultContext = P.DefaultContext
3797        setcontext = P.setcontext
3798
3799        c = DefaultContext.copy()
3800        c.traps = dict((s, 0) for s in OrderedSignals[P])
3801        setcontext(c)
3802
3803        d1 = Decimal('-25e55')
3804        b1 = Decimal('-25e55')
3805        d2 = Decimal('33e+33')
3806        b2 = Decimal('33e+33')
3807
3808        def checkSameDec(operation, useOther=False):
3809            if useOther:
3810                eval("d1." + operation + "(d2)")
3811                self.assertEqual(d1._sign, b1._sign)
3812                self.assertEqual(d1._int, b1._int)
3813                self.assertEqual(d1._exp, b1._exp)
3814                self.assertEqual(d2._sign, b2._sign)
3815                self.assertEqual(d2._int, b2._int)
3816                self.assertEqual(d2._exp, b2._exp)
3817            else:
3818                eval("d1." + operation + "()")
3819                self.assertEqual(d1._sign, b1._sign)
3820                self.assertEqual(d1._int, b1._int)
3821                self.assertEqual(d1._exp, b1._exp)
3822            return
3823
3824        Decimal(d1)
3825        self.assertEqual(d1._sign, b1._sign)
3826        self.assertEqual(d1._int, b1._int)
3827        self.assertEqual(d1._exp, b1._exp)
3828
3829        checkSameDec("__abs__")
3830        checkSameDec("__add__", True)
3831        checkSameDec("__div__", True)
3832        checkSameDec("__divmod__", True)
3833        checkSameDec("__eq__", True)
3834        checkSameDec("__ne__", True)
3835        checkSameDec("__le__", True)
3836        checkSameDec("__lt__", True)
3837        checkSameDec("__ge__", True)
3838        checkSameDec("__gt__", True)
3839        checkSameDec("__float__")
3840        checkSameDec("__floordiv__", True)
3841        checkSameDec("__hash__")
3842        checkSameDec("__int__")
3843        checkSameDec("__trunc__")
3844        checkSameDec("__long__")
3845        checkSameDec("__mod__", True)
3846        checkSameDec("__mul__", True)
3847        checkSameDec("__neg__")
3848        checkSameDec("__nonzero__")
3849        checkSameDec("__pos__")
3850        checkSameDec("__pow__", True)
3851        checkSameDec("__radd__", True)
3852        checkSameDec("__rdiv__", True)
3853        checkSameDec("__rdivmod__", True)
3854        checkSameDec("__repr__")
3855        checkSameDec("__rfloordiv__", True)
3856        checkSameDec("__rmod__", True)
3857        checkSameDec("__rmul__", True)
3858        checkSameDec("__rpow__", True)
3859        checkSameDec("__rsub__", True)
3860        checkSameDec("__str__")
3861        checkSameDec("__sub__", True)
3862        checkSameDec("__truediv__", True)
3863        checkSameDec("adjusted")
3864        checkSameDec("as_tuple")
3865        checkSameDec("compare", True)
3866        checkSameDec("max", True)
3867        checkSameDec("min", True)
3868        checkSameDec("normalize")
3869        checkSameDec("quantize", True)
3870        checkSameDec("remainder_near", True)
3871        checkSameDec("same_quantum", True)
3872        checkSameDec("sqrt")
3873        checkSameDec("to_eng_string")
3874        checkSameDec("to_integral")
3875
3876    def test_py_decimal_id(self):
3877        Decimal = P.Decimal
3878
3879        d = Decimal(45)
3880        e = Decimal(d)
3881        self.assertEqual(str(e), '45')
3882        self.assertNotEqual(id(d), id(e))
3883
3884    def test_py_rescale(self):
3885        # Coverage
3886        Decimal = P.Decimal
3887        ROUND_UP = P.ROUND_UP
3888        localcontext = P.localcontext
3889
3890        with localcontext() as c:
3891            x = Decimal("NaN")._rescale(3, ROUND_UP)
3892            self.assertTrue(x.is_nan())
3893
3894    def test_py__round(self):
3895        # Coverage
3896        Decimal = P.Decimal
3897        ROUND_UP = P.ROUND_UP
3898
3899        self.assertRaises(ValueError, Decimal("3.1234")._round, 0, ROUND_UP)
3900
3901class CFunctionality(unittest.TestCase):
3902    """Extra functionality in _decimal"""
3903
3904    def test_c_ieee_context(self):
3905        # issue 8786: Add support for IEEE 754 contexts to decimal module.
3906        IEEEContext = C.IEEEContext
3907        DECIMAL32 = C.DECIMAL32
3908        DECIMAL64 = C.DECIMAL64
3909        DECIMAL128 = C.DECIMAL128
3910
3911        def assert_rest(self, context):
3912            self.assertEqual(context.clamp, 1)
3913            assert_signals(self, context, 'traps', [])
3914            assert_signals(self, context, 'flags', [])
3915
3916        c = IEEEContext(DECIMAL32)
3917        self.assertEqual(c.prec, 7)
3918        self.assertEqual(c.Emax, 96)
3919        self.assertEqual(c.Emin, -95)
3920        assert_rest(self, c)
3921
3922        c = IEEEContext(DECIMAL64)
3923        self.assertEqual(c.prec, 16)
3924        self.assertEqual(c.Emax, 384)
3925        self.assertEqual(c.Emin, -383)
3926        assert_rest(self, c)
3927
3928        c = IEEEContext(DECIMAL128)
3929        self.assertEqual(c.prec, 34)
3930        self.assertEqual(c.Emax, 6144)
3931        self.assertEqual(c.Emin, -6143)
3932        assert_rest(self, c)
3933
3934        # Invalid values
3935        self.assertRaises(OverflowError, IEEEContext, 2**63)
3936        self.assertRaises(ValueError, IEEEContext, -1)
3937        self.assertRaises(ValueError, IEEEContext, 1024)
3938
3939    def test_apply(self):
3940        # Decimal("9.9999999").apply() applies the current context.
3941        Decimal = C.Decimal
3942        localcontext = C.localcontext
3943
3944        with localcontext() as c:
3945            c.prec = 5
3946            c.Emax = 99999
3947            c.Emin = -99999
3948
3949            d = c.copy()
3950            d.prec = 4
3951
3952            x = Decimal("123456")
3953            self.assertEqual(str(x.apply()), "1.2346E+5")
3954            self.assertEqual(str(c.apply(x)), "1.2346E+5")
3955
3956            self.assertEqual(str(x.apply(d)), "1.235E+5")
3957            self.assertEqual(str(d.apply(x)), "1.235E+5")
3958
3959            self.assertRaises(TypeError, x.apply, "p")
3960            self.assertRaises(TypeError, x.apply, "p", "q")
3961            self.assertRaises(TypeError, c.apply, "p")
3962
3963            x = Decimal(1171**2221)
3964            self.assertEqual(str(x.apply()), "1.8402E+6815")
3965            self.assertEqual(str(c.apply(x)), "1.8402E+6815")
3966            self.assertEqual(str(d.apply(x)), "1.840E+6815")
3967
3968    def test_c_float_operation_default(self):
3969        Decimal = C.Decimal
3970        Context = C.Context
3971        Inexact = C.Inexact
3972        DecInexact = C.DecInexact
3973        FloatOperation= C.FloatOperation
3974        DecFloatOperation= C.DecFloatOperation
3975
3976        context = Context()
3977        self.assertFalse(context.flags[FloatOperation])
3978        self.assertFalse(context.traps[FloatOperation])
3979        self.assertFalse(context._flags&DecFloatOperation)
3980        self.assertFalse(context._traps&DecFloatOperation)
3981
3982        context.settraps([Inexact, FloatOperation])
3983        self.assertEqual(context._traps, DecInexact|DecFloatOperation)
3984        self.assertTrue(context.traps[FloatOperation])
3985        self.assertTrue(context.traps[Inexact])
3986
3987    def test_c_powmod(self):
3988        Decimal = C.Decimal
3989        Context = C.Context
3990
3991        c = Context()
3992        d = c.powmod(Decimal(1), Decimal(4), Decimal(2))
3993        self.assertEqual(c.powmod(1, 4, 2), d)
3994        self.assertEqual(c.powmod(Decimal(1), 4, 2), d)
3995        self.assertEqual(c.powmod(1, Decimal(4), 2), d)
3996        self.assertEqual(c.powmod(1, 4, Decimal(2)), d)
3997        self.assertEqual(c.powmod(Decimal(1), Decimal(4), 2), d)
3998        self.assertRaises(TypeError, c.powmod, '1', 4, 2)
3999        self.assertRaises(TypeError, c.powmod, 1, '4', 2)
4000        self.assertRaises(TypeError, c.powmod, 1, 4, '2')
4001
4002    def test_c_context(self):
4003        Context = C.Context
4004
4005        c = Context(flags=C.DecClamped, traps=C.DecRounded)
4006        self.assertEqual(c._flags, C.DecClamped)
4007        self.assertEqual(c._traps, C.DecRounded)
4008
4009    def test_sundry(self):
4010        Decimal = C.Decimal
4011
4012        # mpd_isinteger
4013        self.assertTrue(Decimal("1.234e5").is_integer())
4014        self.assertTrue(Decimal("snan").is_special())
4015
4016        # Extra functions
4017        self.assertEqual(Decimal(-1).abs(), 1)
4018        self.assertEqual(Decimal(1).minus(), -1)
4019        self.assertEqual(Decimal(1).plus(), 1)
4020        self.assertEqual(Decimal(1).add(1), 2)
4021        self.assertEqual(Decimal(12).div(2), 6)
4022        self.assertEqual(Decimal(10).divint(7), 1)
4023        self.assertEqual(Decimal(10).mul(12), 120)
4024        self.assertEqual(Decimal(10).rem(7), 3)
4025        self.assertEqual(Decimal(10).sub(7), 3)
4026        self.assertEqual(Decimal(10).divmod(7), (1, 3))
4027
4028    def test_constants(self):
4029        # Condition flags
4030        cond = (
4031            C.DecClamped, C.DecConversionSyntax, C.DecDivisionByZero,
4032            C.DecDivisionImpossible, C.DecDivisionUndefined,
4033            C.DecFpuError, C.DecInexact, C.DecInvalidContext,
4034            C.DecInvalidOperation, C.DecMallocError,
4035            C.DecFloatOperation, C.DecOverflow, C.DecRounded,
4036            C.DecSubnormal, C.DecUnderflow
4037        )
4038
4039        # Architecture dependent context limits
4040        if C.MAX_EMAX > 425000000:
4041            self.assertEqual(C.MAX_PREC, 999999999999999999)
4042            self.assertEqual(C.MAX_EMAX, 999999999999999999)
4043            self.assertEqual(C.MIN_EMIN, -999999999999999999)
4044            self.assertEqual(C.MIN_ETINY, -1999999999999999997)
4045        else:
4046            self.assertEqual(C.MAX_PREC, 425000000)
4047            self.assertEqual(C.MAX_EMAX, 425000000)
4048            self.assertEqual(C.MIN_EMIN, -425000000)
4049            self.assertEqual(C.MIN_ETINY, -849999999)
4050
4051	# IEEEContext
4052        self.assertEqual(C.DECIMAL32, 32)
4053        self.assertEqual(C.DECIMAL64, 64)
4054        self.assertEqual(C.DECIMAL128, 128)
4055        self.assertEqual(C.IEEE_CONTEXT_MAX_BITS, 512)
4056
4057        # Rounding modes
4058        for i, v in enumerate(RoundingModes[C]):
4059            self.assertEqual(v, i)
4060        self.assertEqual(C.ROUND_TRUNC, 8)
4061
4062        # Conditions
4063        for i, v in enumerate(cond):
4064            self.assertEqual(v, 1<<i)
4065
4066        self.assertEqual(C.DecIEEEInvalidOperation,
4067                         C.DecConversionSyntax|
4068                         C.DecDivisionImpossible|
4069                         C.DecDivisionUndefined|
4070                         C.DecFpuError|
4071                         C.DecInvalidContext|
4072                         C.DecInvalidOperation|
4073                         C.DecMallocError)
4074
4075        self.assertEqual(C.DecErrors,
4076                         C.DecIEEEInvalidOperation|
4077                         C.DecDivisionByZero)
4078
4079        self.assertEqual(C.DecTraps,
4080                         C.DecErrors|C.DecOverflow|C.DecUnderflow)
4081
4082class CWhitebox(unittest.TestCase):
4083    """Whitebox testing for _decimal"""
4084
4085    def test_bignum(self):
4086        # Not exactly whitebox, but too slow with pydecimal.
4087        if hasattr(C, 'setfailpoint'):
4088            random.seed(randseed)
4089
4090        Decimal = C.Decimal
4091        localcontext = C.localcontext
4092
4093        b1 = 10**35
4094        b2 = 10**36
4095        with localcontext() as c:
4096            c.prec = 1000000
4097            r = 1 if hasattr(C, 'setfailpoint') else 5
4098            for i in range(r):
4099                a = random.randrange(b1, b2)
4100                b = random.randrange(1000, 1200)
4101                x = a ** b
4102                y = Decimal(a) ** Decimal(b)
4103                self.assertEqual(x, y)
4104
4105    def test_c_input_restriction(self):
4106        # Too large for _decimal to be converted exactly
4107        Decimal = C.Decimal
4108        InvalidOperation = C.InvalidOperation
4109        Context = C.Context
4110        localcontext = C.localcontext
4111
4112        with localcontext(Context()):
4113            self.assertRaises(InvalidOperation, Decimal,
4114                              "1e9999999999999999999")
4115            self.assertRaises(InvalidOperation, Decimal,
4116                              u"1e9999999999999999999")
4117
4118    def test_c_context_repr(self):
4119        # This test is _decimal-only because flags are not printed
4120        # in the same order.
4121        DefaultContext = C.DefaultContext
4122        FloatOperation = C.FloatOperation
4123        ROUND_HALF_DOWN = C.ROUND_HALF_DOWN
4124
4125        c = DefaultContext.copy()
4126
4127        c.prec = 425000000
4128        c.Emax = 425000000
4129        c.Emin = -425000000
4130        c.rounding = ROUND_HALF_DOWN
4131        c.capitals = 0
4132        c.clamp = 1
4133        for sig in OrderedSignals[C]:
4134            c.flags[sig] = True
4135            c.traps[sig] = True
4136        c.flags[FloatOperation] = True
4137        c.traps[FloatOperation] = True
4138
4139        s = c.__repr__()
4140        t = "Context(prec=425000000, rounding=ROUND_HALF_DOWN, " \
4141            "Emin=-425000000, Emax=425000000, capitals=0, clamp=1, " \
4142            "flags=[Clamped, InvalidOperation, DivisionByZero, Inexact, " \
4143                   "FloatOperation, Overflow, Rounded, Subnormal, Underflow], " \
4144            "traps=[Clamped, InvalidOperation, DivisionByZero, Inexact, " \
4145                   "FloatOperation, Overflow, Rounded, Subnormal, Underflow])"
4146        self.assertEqual(s, t)
4147
4148    def test_c_context_errors(self):
4149        Context = C.Context
4150        InvalidOperation = C.InvalidOperation
4151        Overflow = C.Overflow
4152        HAVE_CONFIG_64 = (C.MAX_PREC > 425000000)
4153
4154        c = Context()
4155
4156        # SignalDict: input validation
4157        self.assertRaises(TypeError, c.flags.__setitem__, 801, 0)
4158        self.assertRaises(TypeError, c.traps.__setitem__, 801, 0)
4159        self.assertRaises(ValueError, c.flags.__delitem__, Overflow)
4160        self.assertRaises(ValueError, c.traps.__delitem__, InvalidOperation)
4161        self.assertRaises(TypeError, setattr, c, 'flags', ['x'])
4162        self.assertRaises(TypeError, setattr, c,'traps', ['y'])
4163        self.assertRaises(TypeError, setattr, c, 'flags', {0:1})
4164        self.assertRaises(TypeError, setattr, c, 'traps', {0:1})
4165
4166        self.assertRaises(TypeError, c.setflags, ['x'])
4167        self.assertRaises(TypeError, c.settraps, ['y'])
4168        self.assertRaises(TypeError, c.setflags, 'x')
4169        self.assertRaises(TypeError, c.settraps, 'y')
4170
4171        # Input corner cases
4172        int_max = 2**63-1 if HAVE_CONFIG_64 else 2**31-1
4173        gt_max_emax = 10**18 if HAVE_CONFIG_64 else 10**9
4174
4175        # prec, Emax, Emin
4176        for attr in ['prec', 'Emax']:
4177            self.assertRaises(ValueError, setattr, c, attr, gt_max_emax)
4178        self.assertRaises(ValueError, setattr, c, 'Emin', -gt_max_emax)
4179
4180        # prec, Emax, Emin in context constructor
4181        self.assertRaises(ValueError, Context, prec=gt_max_emax)
4182        self.assertRaises(ValueError, Context, Emax=gt_max_emax)
4183        self.assertRaises(ValueError, Context, Emin=-gt_max_emax)
4184
4185        # Overflow in conversion
4186        self.assertRaises(OverflowError, Context, prec=int_max+1)
4187        self.assertRaises(OverflowError, Context, Emax=int_max+1)
4188        self.assertRaises(OverflowError, Context, Emin=-int_max-2)
4189        self.assertRaises(OverflowError, Context, rounding=int_max+1)
4190        self.assertRaises(OverflowError, Context, clamp=int_max+1)
4191        self.assertRaises(OverflowError, Context, capitals=int_max+1)
4192        self.assertRaises(OverflowError, Context, _allcr=int_max+1)
4193
4194        # OverflowError, general ValueError
4195        for attr in ('prec', 'Emin', 'Emax', 'capitals', 'clamp', '_allcr'):
4196            self.assertRaises(OverflowError, setattr, c, attr, int_max+1)
4197            self.assertRaises(OverflowError, setattr, c, attr, -int_max-2)
4198            if sys.platform != 'win32':
4199                self.assertRaises(ValueError, setattr, c, attr, int_max)
4200                self.assertRaises(ValueError, setattr, c, attr, -int_max-1)
4201
4202        # OverflowError, general TypeError
4203        for attr in ('rounding', '_flags', '_traps'):
4204            self.assertRaises(OverflowError, setattr, c, attr, int_max+1)
4205            self.assertRaises(OverflowError, setattr, c, attr, -int_max-2)
4206            if sys.platform != 'win32':
4207                self.assertRaises(TypeError, setattr, c, attr, int_max)
4208                self.assertRaises(TypeError, setattr, c, attr, -int_max-1)
4209
4210        # OverflowError: unsafe_prec, unsafe_emin, unsafe_emax
4211        self.assertRaises(OverflowError, getattr(c, 'unsafe_setprec'), int_max+1)
4212        self.assertRaises(OverflowError, getattr(c, 'unsafe_setemax'), int_max+1)
4213        self.assertRaises(OverflowError, getattr(c, 'unsafe_setemin'), -int_max-2)
4214
4215        # capitals, clamp, _allcr
4216        for attr in ['capitals', 'clamp', '_allcr']:
4217            self.assertRaises(ValueError, setattr, c, attr, -1)
4218            self.assertRaises(ValueError, setattr, c, attr, 2)
4219            self.assertRaises(TypeError, setattr, c, attr, [1,2,3])
4220            if HAVE_CONFIG_64:
4221                self.assertRaises(ValueError, setattr, c, attr, 2**32)
4222                self.assertRaises(ValueError, setattr, c, attr, 2**32+1)
4223
4224        self.assertRaises(ValueError, Context, _allcr=2)
4225
4226        # _flags, _traps
4227        for attr in ['_flags', '_traps']:
4228            self.assertRaises(TypeError, setattr, c, attr, 999999)
4229            self.assertRaises(TypeError, setattr, c, attr, 'x')
4230
4231    def test_c_valid_context(self):
4232        # These tests are for code coverage in _decimal.
4233        DefaultContext = C.DefaultContext
4234        ROUND_HALF_UP = C.ROUND_HALF_UP
4235        Clamped = C.Clamped
4236        Underflow = C.Underflow
4237        Inexact = C.Inexact
4238        Rounded = C.Rounded
4239        Subnormal = C.Subnormal
4240        DecClamped = C.DecClamped
4241        DecUnderflow = C.DecUnderflow
4242        DecInexact = C.DecInexact
4243        DecRounded = C.DecRounded
4244        DecSubnormal = C.DecSubnormal
4245
4246        c = DefaultContext.copy()
4247
4248        # Exercise all getters and setters
4249        c.prec = 34
4250        c.rounding = ROUND_HALF_UP
4251        c.Emax = 3000
4252        c.Emin = -3000
4253        c.capitals = 1
4254        c.clamp = 0
4255        c._flags = DecUnderflow
4256        c._traps = DecClamped
4257        c._allcr = 0
4258
4259        self.assertEqual(c.prec, 34)
4260        self.assertEqual(c.rounding, ROUND_HALF_UP)
4261        self.assertEqual(c.Emin, -3000)
4262        self.assertEqual(c.Emax, 3000)
4263        self.assertEqual(c.capitals, 1)
4264        self.assertEqual(c.clamp, 0)
4265        self.assertEqual(c._flags, DecUnderflow)
4266        self.assertEqual(c._traps, DecClamped)
4267        self.assertEqual(c._allcr, 0)
4268
4269        self.assertEqual(c.Etiny(), -3033)
4270        self.assertEqual(c.Etop(), 2967)
4271
4272        # Set traps/flags from list
4273        c.settraps([Clamped, Underflow])
4274        self.assertEqual(c._traps, DecClamped|DecUnderflow)
4275
4276        c.setflags([Inexact, Rounded, Subnormal])
4277        self.assertEqual(c._flags, DecInexact|DecRounded|DecSubnormal)
4278
4279        # Exercise all unsafe setters
4280        c.unsafe_setprec(999999999)
4281        c.unsafe_setemax(999999999)
4282        c.unsafe_setemin(-999999999)
4283
4284        self.assertEqual(c.prec, 999999999)
4285        self.assertEqual(c.Emax, 999999999)
4286        self.assertEqual(c.Emin, -999999999)
4287
4288    def test_c_round(self):
4289        # Restricted input.
4290        Decimal = C.Decimal
4291        InvalidOperation = C.InvalidOperation
4292        localcontext = C.localcontext
4293        MAX_EMAX = C.MAX_EMAX
4294        MIN_ETINY = C.MIN_ETINY
4295        int_max = 2**63-1 if C.MAX_PREC > 425000000 else 2**31-1
4296
4297        with localcontext() as c:
4298            c.traps[InvalidOperation] = True
4299            self.assertRaises(InvalidOperation, Decimal("1.23").__round__,
4300                              -int_max-1)
4301            self.assertRaises(InvalidOperation, Decimal("1.23").__round__,
4302                              int_max)
4303            self.assertRaises(InvalidOperation, Decimal("1").__round__,
4304                              int(MAX_EMAX+1))
4305            self.assertRaises(C.InvalidOperation, Decimal("1").__round__,
4306                              -int(MIN_ETINY-1))
4307            self.assertRaises(OverflowError, Decimal("1.23").__round__,
4308                              -int_max-2)
4309            self.assertRaises(OverflowError, Decimal("1.23").__round__,
4310                              int_max+1)
4311
4312    def test_c_format(self):
4313        # Restricted input
4314        Decimal = C.Decimal
4315        InvalidOperation = C.InvalidOperation
4316        Rounded = C.Rounded
4317        localcontext = C.localcontext
4318        HAVE_CONFIG_64 = (C.MAX_PREC > 425000000)
4319
4320        self.assertRaises(TypeError, Decimal(1).__format__, "=10.10", [], 9)
4321        self.assertRaises(TypeError, Decimal(1).__format__, "=10.10", 9)
4322        self.assertRaises(TypeError, Decimal(1).__format__, [])
4323
4324        with localcontext() as c:
4325            c.traps[InvalidOperation] = True
4326            c.traps[Rounded] = True
4327            self.assertRaises(ValueError, Decimal(1).__format__, u"<>=10.10")
4328            maxsize = 2**63-1 if HAVE_CONFIG_64 else 2**31-1
4329            self.assertRaises(InvalidOperation, Decimal("1.23456789").__format__,
4330                              u"=%d.1" % maxsize)
4331
4332    def test_c_integral(self):
4333        Decimal = C.Decimal
4334        Inexact = C.Inexact
4335        ROUND_UP = C.ROUND_UP
4336        localcontext = C.localcontext
4337
4338        x = Decimal(10)
4339        self.assertEqual(x.to_integral(), 10)
4340        self.assertRaises(TypeError, x.to_integral, '10')
4341        self.assertRaises(TypeError, x.to_integral, 10, 'x')
4342        self.assertRaises(TypeError, x.to_integral, 10)
4343
4344        self.assertEqual(x.to_integral_value(), 10)
4345        self.assertRaises(TypeError, x.to_integral_value, '10')
4346        self.assertRaises(TypeError, x.to_integral_value, 10, 'x')
4347        self.assertRaises(TypeError, x.to_integral_value, 10)
4348
4349        self.assertEqual(x.to_integral_exact(), 10)
4350        self.assertRaises(TypeError, x.to_integral_exact, '10')
4351        self.assertRaises(TypeError, x.to_integral_exact, 10, 'x')
4352        self.assertRaises(TypeError, x.to_integral_exact, 10)
4353
4354        with localcontext() as c:
4355            x = Decimal("99999999999999999999999999.9").to_integral_value(ROUND_UP)
4356            self.assertEqual(x, Decimal('100000000000000000000000000'))
4357
4358            x = Decimal("99999999999999999999999999.9").to_integral_exact(ROUND_UP)
4359            self.assertEqual(x, Decimal('100000000000000000000000000'))
4360
4361            c.traps[Inexact] = True
4362            self.assertRaises(Inexact, Decimal("999.9").to_integral_exact, ROUND_UP)
4363
4364    def test_c_funcs(self):
4365        # Invalid arguments
4366        Decimal = C.Decimal
4367        InvalidOperation = C.InvalidOperation
4368        DivisionByZero = C.DivisionByZero
4369        ROUND_UP = C.ROUND_UP
4370        getcontext = C.getcontext
4371        localcontext = C.localcontext
4372
4373        self.assertEqual(Decimal('9.99e10').to_sci_string(), '9.99E+10')
4374        self.assertEqual(Decimal('9.99e10').to_eng_string(), '99.9E+9')
4375
4376        self.assertRaises(TypeError, pow, Decimal(1), 2, "3")
4377        self.assertRaises(TypeError, Decimal(9).number_class, "x", "y")
4378        self.assertRaises(TypeError, Decimal(9).divmod, 8, "x", "y")
4379        self.assertRaises(TypeError, Decimal(9).same_quantum, 3, "x", "y")
4380        self.assertRaises(TypeError, Decimal(9).to_sci, 3, "x", "y")
4381        self.assertRaises(TypeError, Decimal(9).to_eng, 3, "x", "y")
4382
4383        self.assertEqual(Decimal("1.234e2007").sign(), 1)
4384        self.assertEqual(Decimal("-1.234e2007").sign(), -1)
4385
4386        self.assertRaises(
4387            TypeError,
4388            Decimal("1.23456789").quantize, Decimal('1e-100000'), []
4389        )
4390        self.assertRaises(
4391            TypeError,
4392            Decimal("1.23456789").quantize, Decimal('1e-100000'), getcontext()
4393        )
4394        self.assertRaises(
4395            TypeError,
4396            Decimal("1.23456789").quantize, Decimal('1e-100000'), 10
4397        )
4398        self.assertRaises(
4399            TypeError,
4400            Decimal("1.23456789").quantize, Decimal('1e-100000'), ROUND_UP, 1000
4401        )
4402
4403        with localcontext() as c:
4404            c.clear_traps()
4405
4406            # Invalid arguments
4407            self.assertRaises(TypeError, c.copy_sign, Decimal(1), "x", "y")
4408            self.assertRaises(TypeError, c.canonical, 200)
4409            self.assertRaises(TypeError, c.is_canonical, 200)
4410            self.assertRaises(TypeError, c.divmod, 9, 8, "x", "y")
4411            self.assertRaises(TypeError, c.same_quantum, 9, 3, "x", "y")
4412
4413            self.assertEqual(str(c.canonical(Decimal(200))), '200')
4414            self.assertEqual(c.radix(), 10)
4415
4416            c.traps[DivisionByZero] = True
4417            self.assertRaises(DivisionByZero, Decimal(9).__divmod__, 0)
4418            self.assertRaises(DivisionByZero, Decimal(9).divmod, 0)
4419            self.assertRaises(DivisionByZero, c.divmod, 9, 0)
4420            self.assertTrue(c.flags[InvalidOperation])
4421
4422            c.clear_flags()
4423            c.traps[InvalidOperation] = True
4424            self.assertRaises(InvalidOperation, Decimal(9).__divmod__, 0)
4425            self.assertRaises(InvalidOperation, Decimal(9).divmod, 0)
4426            self.assertRaises(InvalidOperation, c.divmod, 9, 0)
4427            self.assertTrue(c.flags[DivisionByZero])
4428
4429            c.traps[InvalidOperation] = True
4430            c.prec = 2
4431            self.assertRaises(InvalidOperation, pow, Decimal(1000), 1, 501)
4432
4433            c.prec = 10
4434            x = Decimal(2).invroot()
4435            self.assertEqual(str(x), '0.7071067812')
4436
4437            x = c.invroot(3)
4438            self.assertEqual(str(x), '0.5773502692')
4439
4440            c.prec = 28
4441            x = Decimal(2).power(8)
4442            self.assertEqual(str(x), '256')
4443
4444            x = Decimal(2).powmod(8, 31)
4445            self.assertEqual(str(x), '8')
4446
4447    def test_c_context_templates(self):
4448        self.assertEqual(
4449            C.BasicContext._traps,
4450            C.DecIEEEInvalidOperation|C.DecDivisionByZero|C.DecOverflow|
4451            C.DecUnderflow|C.DecClamped
4452        )
4453        self.assertEqual(
4454            C.DefaultContext._traps,
4455            C.DecIEEEInvalidOperation|C.DecDivisionByZero|C.DecOverflow
4456        )
4457
4458    def test_c_signal_dict(self):
4459        if hasattr(C, 'setfailpoint'):
4460            random.seed(randseed)
4461
4462        # SignalDict coverage
4463        Context = C.Context
4464        DefaultContext = C.DefaultContext
4465
4466        InvalidOperation = C.InvalidOperation
4467        DivisionByZero = C.DivisionByZero
4468        Overflow = C.Overflow
4469        Subnormal = C.Subnormal
4470        Underflow = C.Underflow
4471        Rounded = C.Rounded
4472        Inexact = C.Inexact
4473        Clamped = C.Clamped
4474
4475        DecClamped = C.DecClamped
4476        DecInvalidOperation = C.DecInvalidOperation
4477        DecIEEEInvalidOperation = C.DecIEEEInvalidOperation
4478
4479        def assertIsExclusivelySet(signal, signal_dict):
4480            for sig in signal_dict:
4481                if sig == signal:
4482                    self.assertTrue(signal_dict[sig])
4483                else:
4484                    self.assertFalse(signal_dict[sig])
4485
4486        c = DefaultContext.copy()
4487
4488        # Signal dict methods
4489        self.assertTrue(Overflow in c.traps)
4490        self.assertTrue(c.traps.has_key(Overflow))
4491
4492        c.clear_traps()
4493        for k in c.traps.iterkeys():
4494            c.traps[k] = True
4495        for v in c.traps.itervalues():
4496            self.assertTrue(v)
4497        c.clear_traps()
4498        for k, v in c.traps.iteritems():
4499            self.assertFalse(v)
4500
4501        c.clear_traps()
4502        for k in c.traps.keys():
4503            c.traps[k] = True
4504        for v in c.traps.values():
4505            self.assertTrue(v)
4506        c.clear_traps()
4507        for k, v in c.traps.iteritems():
4508            self.assertFalse(v)
4509
4510        self.assertFalse(c.flags.get(Overflow))
4511        self.assertTrue(c.flags.get("x") is None)
4512        self.assertEqual(c.flags.get("x", "y"), "y")
4513        self.assertRaises(TypeError, c.flags.get, "x", "y", "z")
4514
4515        self.assertEqual(len(c.flags), len(c.traps))
4516        s = sys.getsizeof(c.flags)
4517        s = sys.getsizeof(c.traps)
4518        s = c.flags.__repr__()
4519
4520        # Set flags/traps form long.
4521        c.clear_flags()
4522        c._flags = long(DecClamped)
4523        self.assertTrue(c.flags[Clamped])
4524
4525        c.clear_traps()
4526        c._traps = long(DecInvalidOperation)
4527        self.assertTrue(c.traps[InvalidOperation])
4528
4529        # Set flags/traps from dictionary.
4530        c.clear_flags()
4531        d = c.flags.copy()
4532        d[DivisionByZero] = True
4533        c.flags = d
4534        assertIsExclusivelySet(DivisionByZero, c.flags)
4535
4536        c.clear_traps()
4537        d = c.traps.copy()
4538        d[Underflow] = True
4539        c.traps = d
4540        assertIsExclusivelySet(Underflow, c.traps)
4541
4542        # Random constructors
4543        IntSignals = {
4544          Clamped: C.DecClamped,
4545          Rounded: C.DecRounded,
4546          Inexact: C.DecInexact,
4547          Subnormal: C.DecSubnormal,
4548          Underflow: C.DecUnderflow,
4549          Overflow: C.DecOverflow,
4550          DivisionByZero: C.DecDivisionByZero,
4551          InvalidOperation: C.DecIEEEInvalidOperation
4552        }
4553        IntCond = [
4554          C.DecDivisionImpossible, C.DecDivisionUndefined, C.DecFpuError,
4555          C.DecInvalidContext, C.DecInvalidOperation, C.DecMallocError,
4556          C.DecConversionSyntax,
4557        ]
4558
4559        lim = 1 if hasattr(C, 'setfailpoint') else len(OrderedSignals[C])
4560        for r in range(lim):
4561            for t in range(lim):
4562                for round in RoundingModes[C]:
4563                    flags = random.sample(OrderedSignals[C], r)
4564                    traps = random.sample(OrderedSignals[C], t)
4565                    prec = random.randrange(1, 10000)
4566                    emin = random.randrange(-10000, 0)
4567                    emax = random.randrange(0, 10000)
4568                    clamp = random.randrange(0, 2)
4569                    caps = random.randrange(0, 2)
4570                    cr = random.randrange(0, 2)
4571                    c = Context(prec=prec, rounding=round, Emin=emin, Emax=emax,
4572                                capitals=caps, clamp=clamp, flags=list(flags),
4573                                traps=list(traps), _allcr=cr)
4574
4575                    self.assertEqual(c.prec, prec)
4576                    self.assertEqual(c.rounding, round)
4577                    self.assertEqual(c.Emin, emin)
4578                    self.assertEqual(c.Emax, emax)
4579                    self.assertEqual(c.capitals, caps)
4580                    self.assertEqual(c.clamp, clamp)
4581                    self.assertEqual(c._allcr, cr)
4582
4583                    f = 0
4584                    for x in flags:
4585                        f |= IntSignals[x]
4586                    self.assertEqual(c._flags, f)
4587
4588                    f = 0
4589                    for x in traps:
4590                        f |= IntSignals[x]
4591                    self.assertEqual(c._traps, f)
4592
4593        for cond in IntCond:
4594            c._flags = cond
4595            self.assertTrue(c._flags&DecIEEEInvalidOperation)
4596            assertIsExclusivelySet(InvalidOperation, c.flags)
4597
4598        for cond in IntCond:
4599            c._traps = cond
4600            self.assertTrue(c._traps&DecIEEEInvalidOperation)
4601            assertIsExclusivelySet(InvalidOperation, c.traps)
4602
4603
4604all_tests = [
4605  CExplicitConstructionTest, PyExplicitConstructionTest,
4606  CImplicitConstructionTest, PyImplicitConstructionTest,
4607  CFormatTest,               PyFormatTest,
4608  CArithmeticOperatorsTest,  PyArithmeticOperatorsTest,
4609  CThreadingTest,            PyThreadingTest,
4610  CUsabilityTest,            PyUsabilityTest,
4611  CPythonAPItests,           PyPythonAPItests,
4612  CContextAPItests,          PyContextAPItests,
4613  CContextWithStatement,     PyContextWithStatement,
4614  CContextFlags,             PyContextFlags,
4615  CSpecialContexts,          PySpecialContexts,
4616  CContextInputValidation,   PyContextInputValidation,
4617  CCoverage,                 PyCoverage,
4618  CFunctionality,            PyFunctionality,
4619  CWhitebox,                 PyWhitebox,
4620  CIBMTestCases,             PyIBMTestCases,
4621]
4622
4623if py_minor <= 6:
4624    all_tests = all_tests[::2]
4625
4626# Wrap test functions for testing api failures. Doing this in
4627# test_main() causes spurious refleaks, so it is done here.
4628if hasattr(C, 'setapicalls'):
4629    for cls in all_tests:
4630        if cls == CIBMTestCases or cls == PyIBMTestCases:
4631            newfunc = withFailpoint(getattr(cls, 'eval_equation'))
4632            setattr(cls, 'eval_equation', newfunc)
4633        else:
4634            for attr in dir(cls):
4635                if attr.startswith('test_'):
4636                    if attr == 'test_threading':
4637                        continue
4638                    newfunc = withFailpoint(getattr(cls, attr))
4639                    setattr(cls, attr, newfunc)
4640
4641def test_main(arith=False, verbose=None, todo_tests=None, debug=None):
4642    """ Execute the tests.
4643
4644    Runs all arithmetic tests if arith is True or if the "decimal" resource
4645    is enabled in regrtest.py
4646    """
4647
4648    init(C)
4649    init(P)
4650    global TEST_ALL, DEBUG
4651    TEST_ALL = arith or is_resource_enabled('decimal')
4652    DEBUG = debug
4653
4654    if todo_tests is None:
4655        test_classes = all_tests
4656    else:
4657        test_classes = [CIBMTestCases, PyIBMTestCases]
4658
4659    # Dynamically build custom test definition for each file in the test
4660    # directory and add the definitions to the DecimalTest class.  This
4661    # procedure insures that new files do not get skipped.
4662    for filename in os.listdir(directory):
4663        if '.decTest' not in filename or filename.startswith("."):
4664            continue
4665        head, tail = filename.split('.')
4666        if todo_tests is not None and head not in todo_tests:
4667            continue
4668        tester = lambda self, f=filename: self.eval_file(directory + f)
4669        setattr(CIBMTestCases, 'test_' + head, tester)
4670        setattr(PyIBMTestCases, 'test_' + head, tester)
4671        del filename, head, tail, tester
4672
4673
4674    try:
4675        run_unittest(*test_classes)
4676        if todo_tests is None:
4677            run_doctest(C, verbose)
4678            run_doctest(P, verbose)
4679    finally:
4680        if C: C.setcontext(ORIGINAL_CONTEXT[C])
4681        P.setcontext(ORIGINAL_CONTEXT[P])
4682        if not C:
4683            warnings.warn('C tests skipped: no module named _decimal.',
4684                          UserWarning)
4685        if not orig_sys_decimal is sys.modules['decimal']:
4686            raise TestFailed("Internal error: unbalanced number of changes to "
4687                             "sys.modules['decimal'].")
4688
4689
4690if __name__ == '__main__':
4691    import optparse
4692    p = optparse.OptionParser("test_decimal.py [--debug] [{--skip | test1 [test2 [...]]}]")
4693    p.add_option('--debug', '-d', action='store_true', help='shows the test number and context before each test')
4694    p.add_option('--skip',  '-s', action='store_true', help='skip over 90% of the arithmetic tests')
4695    (opt, args) = p.parse_args()
4696
4697    if opt.skip:
4698        test_main(arith=False, verbose=True)
4699    elif args:
4700        test_main(arith=True, verbose=True, todo_tests=args, debug=opt.debug)
4701    else:
4702        test_main(arith=True, verbose=True)
4703