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