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