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