diff options
author | Mark Dickinson <dickinsm@gmail.com> | 2010-04-02 10:17:07 +0000 |
---|---|---|
committer | Mark Dickinson <dickinsm@gmail.com> | 2010-04-02 10:17:07 +0000 |
commit | e096e82e827f6092706c7349fd4944c275382eb5 (patch) | |
tree | 9d9f8a1f53574d56a605499484d44508c252ef62 /Lib/test/test_decimal.py | |
parent | ea2d38947461039b49ff2f04d28bf14bf92194df (diff) | |
download | cpython-git-e096e82e827f6092706c7349fd4944c275382eb5.tar.gz |
Issue #7279: Make comparisons involving a Decimal sNaN signal InvalidOperation.
Diffstat (limited to 'Lib/test/test_decimal.py')
-rw-r--r-- | Lib/test/test_decimal.py | 55 |
1 files changed, 47 insertions, 8 deletions
diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 4071eff8db..c2a6b0e007 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -26,6 +26,7 @@ with the corresponding argument. import math import os, sys +import operator import pickle, copy import unittest from decimal import * @@ -1080,18 +1081,56 @@ class DecimalArithmeticOperatorsTest(unittest.TestCase): self.assertEqual(abs(Decimal(45)), abs(Decimal(-45))) # abs def test_nan_comparisons(self): + # comparisons involving signaling nans signal InvalidOperation + + # order comparisons (<, <=, >, >=) involving only quiet nans + # also signal InvalidOperation + + # equality comparisons (==, !=) involving only quiet nans + # don't signal, but return False or True respectively. + n = Decimal('NaN') s = Decimal('sNaN') i = Decimal('Inf') f = Decimal('2') - for x, y in [(n, n), (n, i), (i, n), (n, f), (f, n), - (s, n), (n, s), (s, i), (i, s), (s, f), (f, s), (s, s)]: - self.assertTrue(x != y) - self.assertTrue(not (x == y)) - self.assertTrue(not (x < y)) - self.assertTrue(not (x <= y)) - self.assertTrue(not (x > y)) - self.assertTrue(not (x >= y)) + + qnan_pairs = (n, n), (n, i), (i, n), (n, f), (f, n) + snan_pairs = (s, n), (n, s), (s, i), (i, s), (s, f), (f, s), (s, s) + order_ops = operator.lt, operator.le, operator.gt, operator.ge + equality_ops = operator.eq, operator.ne + + # results when InvalidOperation is not trapped + for x, y in qnan_pairs + snan_pairs: + for op in order_ops + equality_ops: + got = op(x, y) + expected = True if op is operator.ne else False + self.assertIs(expected, got, + "expected {0!r} for operator.{1}({2!r}, {3!r}); " + "got {4!r}".format( + expected, op.__name__, x, y, got)) + + # repeat the above, but this time trap the InvalidOperation + with localcontext() as ctx: + ctx.traps[InvalidOperation] = 1 + + for x, y in qnan_pairs: + for op in equality_ops: + got = op(x, y) + expected = True if op is operator.ne else False + self.assertIs(expected, got, + "expected {0!r} for " + "operator.{1}({2!r}, {3!r}); " + "got {4!r}".format( + expected, op.__name__, x, y, got)) + + for x, y in snan_pairs: + for op in equality_ops: + self.assertRaises(InvalidOperation, operator.eq, x, y) + self.assertRaises(InvalidOperation, operator.ne, x, y) + + for x, y in qnan_pairs + snan_pairs: + for op in order_ops: + self.assertRaises(InvalidOperation, op, x, y) def test_copy_sign(self): d = Decimal(1).copy_sign(Decimal(-2)) |