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