aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_decimal.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_decimal.py')
-rw-r--r--Lib/test/test_decimal.py250
1 files changed, 166 insertions, 84 deletions
diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py
index 3e184efc2e1..30d397178d0 100644
--- a/Lib/test/test_decimal.py
+++ b/Lib/test/test_decimal.py
@@ -27,12 +27,14 @@ with the corresponding argument.
import math
import os, sys
import operator
+import warnings
import pickle, copy
import unittest
from decimal import *
import numbers
-from test.test_support import (run_unittest, run_doctest,
- is_resource_enabled, check_py3k_warnings)
+from test.support import (run_unittest, run_doctest, is_resource_enabled,
+ requires_IEEE_754)
+from test.support import check_warnings
import random
try:
import threading
@@ -60,11 +62,6 @@ def init():
)
setcontext(DefaultTestContext)
-# decorator for skipping tests on non-IEEE 754 platforms
-requires_IEEE_754 = unittest.skipUnless(
- float.__getformat__("double").startswith("IEEE"),
- "test requires IEEE 754 doubles")
-
TESTDATADIR = 'decimaltestdata'
if __name__ == '__main__':
file = sys.argv[0]
@@ -255,7 +252,7 @@ class DecimalTest(unittest.TestCase):
return self.eval_equation(s)
def eval_directive(self, s):
- funct, value = map(lambda x: x.strip().lower(), s.split(':'))
+ funct, value = (x.strip().lower() for x in s.split(':'))
if funct == 'rounding':
value = RoundingDict[value]
else:
@@ -279,7 +276,7 @@ class DecimalTest(unittest.TestCase):
L = Sides[0].strip().split()
id = L[0]
if DEBUG:
- print "Test ", id,
+ print("Test ", id, end=" ")
funct = L[1].lower()
valstemp = L[2:]
L = Sides[1].strip().split()
@@ -327,7 +324,7 @@ class DecimalTest(unittest.TestCase):
funct(self.context.create_decimal(v))
except error:
pass
- except Signals, e:
+ except Signals as e:
self.fail("Raised %s in %s when %s disabled" % \
(e, s, error))
else:
@@ -347,7 +344,7 @@ class DecimalTest(unittest.TestCase):
funct(*vals)
except error:
pass
- except Signals, e:
+ except Signals as e:
self.fail("Raised %s in %s when %s disabled" % \
(e, s, error))
else:
@@ -362,7 +359,7 @@ class DecimalTest(unittest.TestCase):
funct(*vals)
except error:
pass
- except Signals, e:
+ except Signals as e:
self.fail("Raised %s in %s; expected %s" %
(type(e), s, error))
else:
@@ -373,23 +370,26 @@ class DecimalTest(unittest.TestCase):
if DEBUG:
- print "--", self.context
+ print("--", self.context)
try:
result = str(funct(*vals))
if fname in LOGICAL_FUNCTIONS:
result = str(int(eval(result))) # 'True', 'False' -> '1', '0'
- except Signals, error:
+ except Signals as error:
self.fail("Raised %s in %s" % (error, s))
except: #Catch any error long enough to state the test case.
- print "ERROR:", s
+ print("ERROR:", s)
raise
myexceptions = self.getexceptions()
self.context.clear_flags()
+ myexceptions.sort(key=repr)
+ theirexceptions.sort(key=repr)
+
self.assertEqual(result, ans,
'Incorrect answer for ' + s + ' -- got ' + result)
- self.assertItemsEqual(myexceptions, theirexceptions,
+ self.assertEqual(myexceptions, theirexceptions,
'Incorrect flags set in ' + s + ' -- got ' + str(myexceptions))
return
@@ -405,7 +405,7 @@ class DecimalTest(unittest.TestCase):
def change_max_exponent(self, exp):
self.context.Emax = exp
def change_clamp(self, clamp):
- self.context._clamp = clamp
+ self.context.clamp = clamp
@@ -459,12 +459,6 @@ class DecimalExplicitConstructionTest(unittest.TestCase):
self.assertEqual(str(Decimal('1.3E4 \n')), '1.3E+4')
self.assertEqual(str(Decimal(' -7.89')), '-7.89')
- #unicode strings should be permitted
- self.assertEqual(str(Decimal(u'0E-017')), '0E-17')
- self.assertEqual(str(Decimal(u'45')), '45')
- self.assertEqual(str(Decimal(u'-Inf')), '-Infinity')
- self.assertEqual(str(Decimal(u'NaN123')), 'NaN123')
-
def test_explicit_from_tuples(self):
#zero
@@ -600,9 +594,9 @@ class DecimalExplicitConstructionTest(unittest.TestCase):
def test_unicode_digits(self):
test_values = {
- u'\uff11': '1',
- u'\u0660.\u0660\u0663\u0667\u0662e-\u0663' : '0.0000372',
- u'-nan\u0c68\u0c6a\u0c66\u0c66' : '-NaN2400',
+ '\uff11': '1',
+ '\u0660.\u0660\u0663\u0667\u0662e-\u0663' : '0.0000372',
+ '-nan\u0c68\u0c6a\u0c66\u0c66' : '-NaN2400',
}
for input, expected in test_values.items():
self.assertEqual(str(Decimal(input)), expected)
@@ -663,17 +657,11 @@ class DecimalImplicitConstructionTest(unittest.TestCase):
('+', '__add__', '__radd__'),
('-', '__sub__', '__rsub__'),
('*', '__mul__', '__rmul__'),
+ ('/', '__truediv__', '__rtruediv__'),
('%', '__mod__', '__rmod__'),
('//', '__floordiv__', '__rfloordiv__'),
('**', '__pow__', '__rpow__')
]
- with check_py3k_warnings():
- if 1 / 2 == 0:
- # testing with classic division, so add __div__
- oplist.append(('/', '__div__', '__rdiv__'))
- else:
- # testing with -Qnew, so add __truediv__
- oplist.append(('/', '__truediv__', '__rtruediv__'))
for sym, lop, rop in oplist:
setattr(E, lop, lambda self, other: 'str' + lop + str(other))
@@ -826,6 +814,18 @@ class DecimalFormatTest(unittest.TestCase):
# issue 6850
('a=-7.0', '0.12345', 'aaaa0.1'),
+
+ # Issue 7094: Alternate formatting (specified by #)
+ ('.0e', '1.0', '1e+0'),
+ ('#.0e', '1.0', '1.e+0'),
+ ('.0f', '1.0', '1'),
+ ('#.0f', '1.0', '1.'),
+ ('g', '1.1', '1.1'),
+ ('#g', '1.1', '1.1'),
+ ('.0g', '1', '1'),
+ ('#.0g', '1', '1.'),
+ ('.0%', '1.0', '100%'),
+ ('#.0%', '1.0', '100.%'),
]
for fmt, d, result in test_values:
self.assertEqual(format(Decimal(d), fmt), result)
@@ -1263,17 +1263,11 @@ class DecimalUsabilityTest(unittest.TestCase):
self.assertNotEqual(da, dc)
self.assertLessEqual(da, db)
self.assertGreaterEqual(da, db)
- self.assertEqual(cmp(dc,da), 1)
- self.assertEqual(cmp(da,dc), -1)
- self.assertEqual(cmp(da,db), 0)
#a Decimal and an int
self.assertGreater(dc, 23)
self.assertLess(23, dc)
self.assertEqual(dc, 45)
- self.assertEqual(cmp(dc,23), 1)
- self.assertEqual(cmp(23,dc), -1)
- self.assertEqual(cmp(dc,45), 0)
#a Decimal and uncomparable
self.assertNotEqual(da, 'ugly')
@@ -1282,17 +1276,12 @@ class DecimalUsabilityTest(unittest.TestCase):
self.assertNotEqual(da, object)
# sortable
- a = map(Decimal, xrange(100))
+ a = list(map(Decimal, range(100)))
b = a[:]
random.shuffle(a)
a.sort()
self.assertEqual(a, b)
- # with None
- with check_py3k_warnings():
- self.assertFalse(Decimal(1) < None)
- self.assertTrue(Decimal(1) > None)
-
def test_decimal_float_comparison(self):
da = Decimal('0.25')
db = Decimal('3.0')
@@ -1318,19 +1307,26 @@ class DecimalUsabilityTest(unittest.TestCase):
self.assertEqual(id(dc), id(d))
def test_hash_method(self):
+ def hashit(d):
+ a = hash(d)
+ b = d.__hash__()
+ self.assertEqual(a, b)
+ return a
+
#just that it's hashable
- hash(Decimal(23))
- hash(Decimal('Infinity'))
- hash(Decimal('-Infinity'))
- hash(Decimal('nan123'))
- hash(Decimal('-NaN'))
+ hashit(Decimal(23))
+ hashit(Decimal('Infinity'))
+ hashit(Decimal('-Infinity'))
+ hashit(Decimal('nan123'))
+ hashit(Decimal('-NaN'))
test_values = [Decimal(sign*(2**m + n))
for m in [0, 14, 15, 16, 17, 30, 31,
- 32, 33, 62, 63, 64, 65, 66]
+ 32, 33, 61, 62, 63, 64, 65, 66]
for n in range(-10, 10)
for sign in [-1, 1]]
test_values.extend([
+ Decimal("-1"), # ==> -2
Decimal("-0"), # zeros
Decimal("0.00"),
Decimal("-0.000"),
@@ -1354,13 +1350,13 @@ class DecimalUsabilityTest(unittest.TestCase):
# check that hash(d) == hash(int(d)) for integral values
for value in test_values:
- self.assertEqual(hash(value), hash(int(value)))
+ self.assertEqual(hashit(value), hashit(int(value)))
#the same hash that to an int
- self.assertEqual(hash(Decimal(23)), hash(23))
+ self.assertEqual(hashit(Decimal(23)), hashit(23))
self.assertRaises(TypeError, hash, Decimal('sNaN'))
- self.assertTrue(hash(Decimal('Inf')))
- self.assertTrue(hash(Decimal('-Inf')))
+ self.assertTrue(hashit(Decimal('Inf')))
+ self.assertTrue(hashit(Decimal('-Inf')))
# check that the hashes of a Decimal float match when they
# represent exactly the same values
@@ -1369,7 +1365,7 @@ class DecimalUsabilityTest(unittest.TestCase):
for s in test_strings:
f = float(s)
d = Decimal(s)
- self.assertEqual(hash(f), hash(d))
+ self.assertEqual(hashit(f), hashit(d))
# check that the value of the hash doesn't depend on the
# current context (issue #1757)
@@ -1378,11 +1374,11 @@ class DecimalUsabilityTest(unittest.TestCase):
x = Decimal("123456789.1")
c.prec = 6
- h1 = hash(x)
+ h1 = hashit(x)
c.prec = 10
- h2 = hash(x)
+ h2 = hashit(x)
c.prec = 16
- h3 = hash(x)
+ h3 = hashit(x)
self.assertEqual(h1, h2)
self.assertEqual(h1, h3)
@@ -1420,18 +1416,8 @@ class DecimalUsabilityTest(unittest.TestCase):
self.assertEqual(str(d), '15.32') # str
self.assertEqual(repr(d), "Decimal('15.32')") # repr
- # result type of string methods should be str, not unicode
- unicode_inputs = [u'123.4', u'0.5E2', u'Infinity', u'sNaN',
- u'-0.0E100', u'-NaN001', u'-Inf']
-
- for u in unicode_inputs:
- d = Decimal(u)
- self.assertEqual(type(str(d)), str)
- self.assertEqual(type(repr(d)), str)
- self.assertEqual(type(d.to_eng_string()), str)
-
def test_tonum_methods(self):
- #Test float, int and long methods.
+ #Test float and int methods.
d1 = Decimal('66')
d2 = Decimal('15.32')
@@ -1440,14 +1426,96 @@ class DecimalUsabilityTest(unittest.TestCase):
self.assertEqual(int(d1), 66)
self.assertEqual(int(d2), 15)
- #long
- self.assertEqual(long(d1), 66)
- self.assertEqual(long(d2), 15)
-
#float
self.assertEqual(float(d1), 66)
self.assertEqual(float(d2), 15.32)
+ #floor
+ test_pairs = [
+ ('123.00', 123),
+ ('3.2', 3),
+ ('3.54', 3),
+ ('3.899', 3),
+ ('-2.3', -3),
+ ('-11.0', -11),
+ ('0.0', 0),
+ ('-0E3', 0),
+ ]
+ for d, i in test_pairs:
+ self.assertEqual(math.floor(Decimal(d)), i)
+ self.assertRaises(ValueError, math.floor, Decimal('-NaN'))
+ self.assertRaises(ValueError, math.floor, Decimal('sNaN'))
+ self.assertRaises(ValueError, math.floor, Decimal('NaN123'))
+ self.assertRaises(OverflowError, math.floor, Decimal('Inf'))
+ self.assertRaises(OverflowError, math.floor, Decimal('-Inf'))
+
+ #ceiling
+ test_pairs = [
+ ('123.00', 123),
+ ('3.2', 4),
+ ('3.54', 4),
+ ('3.899', 4),
+ ('-2.3', -2),
+ ('-11.0', -11),
+ ('0.0', 0),
+ ('-0E3', 0),
+ ]
+ for d, i in test_pairs:
+ self.assertEqual(math.ceil(Decimal(d)), i)
+ self.assertRaises(ValueError, math.ceil, Decimal('-NaN'))
+ self.assertRaises(ValueError, math.ceil, Decimal('sNaN'))
+ self.assertRaises(ValueError, math.ceil, Decimal('NaN123'))
+ self.assertRaises(OverflowError, math.ceil, Decimal('Inf'))
+ self.assertRaises(OverflowError, math.ceil, Decimal('-Inf'))
+
+ #round, single argument
+ test_pairs = [
+ ('123.00', 123),
+ ('3.2', 3),
+ ('3.54', 4),
+ ('3.899', 4),
+ ('-2.3', -2),
+ ('-11.0', -11),
+ ('0.0', 0),
+ ('-0E3', 0),
+ ('-3.5', -4),
+ ('-2.5', -2),
+ ('-1.5', -2),
+ ('-0.5', 0),
+ ('0.5', 0),
+ ('1.5', 2),
+ ('2.5', 2),
+ ('3.5', 4),
+ ]
+ for d, i in test_pairs:
+ self.assertEqual(round(Decimal(d)), i)
+ self.assertRaises(ValueError, round, Decimal('-NaN'))
+ self.assertRaises(ValueError, round, Decimal('sNaN'))
+ self.assertRaises(ValueError, round, Decimal('NaN123'))
+ self.assertRaises(OverflowError, round, Decimal('Inf'))
+ self.assertRaises(OverflowError, round, Decimal('-Inf'))
+
+ #round, two arguments; this is essentially equivalent
+ #to quantize, which is already extensively tested
+ test_triples = [
+ ('123.456', -4, '0E+4'),
+ ('123.456', -3, '0E+3'),
+ ('123.456', -2, '1E+2'),
+ ('123.456', -1, '1.2E+2'),
+ ('123.456', 0, '123'),
+ ('123.456', 1, '123.5'),
+ ('123.456', 2, '123.46'),
+ ('123.456', 3, '123.456'),
+ ('123.456', 4, '123.4560'),
+ ('123.455', 2, '123.46'),
+ ('123.445', 2, '123.44'),
+ ('Inf', 4, 'NaN'),
+ ('-Inf', -23, 'NaN'),
+ ('sNaN314', 3, 'NaN314'),
+ ]
+ for d, n, r in test_triples:
+ self.assertEqual(str(round(Decimal(d), n)), r)
+
def test_nan_to_float(self):
# Test conversions of decimal NANs to float.
# See http://bugs.python.org/issue15544
@@ -1549,7 +1617,6 @@ class DecimalUsabilityTest(unittest.TestCase):
checkSameDec("__abs__")
checkSameDec("__add__", True)
- checkSameDec("__div__", True)
checkSameDec("__divmod__", True)
checkSameDec("__eq__", True)
checkSameDec("__ne__", True)
@@ -1562,15 +1629,13 @@ class DecimalUsabilityTest(unittest.TestCase):
checkSameDec("__hash__")
checkSameDec("__int__")
checkSameDec("__trunc__")
- checkSameDec("__long__")
checkSameDec("__mod__", True)
checkSameDec("__mul__", True)
checkSameDec("__neg__")
- checkSameDec("__nonzero__")
+ checkSameDec("__bool__")
checkSameDec("__pos__")
checkSameDec("__pow__", True)
checkSameDec("__radd__", True)
- checkSameDec("__rdiv__", True)
checkSameDec("__rdivmod__", True)
checkSameDec("__repr__")
checkSameDec("__rfloordiv__", True)
@@ -1691,11 +1756,6 @@ class DecimalPythonAPItests(unittest.TestCase):
self.assertRaises(OverflowError, int, Decimal('inf'))
self.assertRaises(OverflowError, int, Decimal('-inf'))
- self.assertRaises(ValueError, long, Decimal('-nan'))
- self.assertRaises(ValueError, long, Decimal('snan'))
- self.assertRaises(OverflowError, long, Decimal('inf'))
- self.assertRaises(OverflowError, long, Decimal('-inf'))
-
def test_trunc(self):
for x in range(-250, 250):
s = '%0.2f' % (x / 100.0)
@@ -1777,6 +1837,26 @@ class ContextAPItests(unittest.TestCase):
self.assertNotEqual(id(c.flags), id(d.flags))
self.assertNotEqual(id(c.traps), id(d.traps))
+ def test__clamp(self):
+ # In Python 3.2, the private attribute `_clamp` was made
+ # public (issue 8540), with the old `_clamp` becoming a
+ # property wrapping `clamp`. For the duration of Python 3.2
+ # only, the attribute should be gettable/settable via both
+ # `clamp` and `_clamp`; in Python 3.3, `_clamp` should be
+ # removed.
+ c = Context(clamp = 0)
+ self.assertEqual(c.clamp, 0)
+
+ with check_warnings(("", DeprecationWarning)):
+ c._clamp = 1
+ self.assertEqual(c.clamp, 1)
+ with check_warnings(("", DeprecationWarning)):
+ self.assertEqual(c._clamp, 1)
+ c.clamp = 0
+ self.assertEqual(c.clamp, 0)
+ with check_warnings(("", DeprecationWarning)):
+ self.assertEqual(c._clamp, 0)
+
def test_abs(self):
c = Context()
d = c.abs(Decimal(-1))
@@ -2274,14 +2354,16 @@ class ContextFlags(unittest.TestCase):
for flag in extra_flags:
if flag not in expected_flags:
expected_flags.append(flag)
+ expected_flags.sort(key=id)
# flags we actually got
new_flags = [k for k,v in context.flags.items() if v]
+ new_flags.sort(key=id)
self.assertEqual(ans, new_ans,
"operation produces different answers depending on flags set: " +
"expected %s, got %s." % (ans, new_ans))
- self.assertItemsEqual(new_flags, expected_flags,
+ self.assertEqual(new_flags, expected_flags,
"operation raises different flags depending on flags set: " +
"expected %s, got %s" % (expected_flags, new_flags))