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