diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index d00ed5aa40c..3ca5927f79e 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -1992,7 +1992,8 @@ class UsabilityTest(unittest.TestCase): d = Decimal("-4.34913534E-17") self.assertEqual(d.as_tuple(), (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) ) - # XXX non-compliant infinity payload. + # The '0' coefficient is implementation specific to decimal.py. + # It has no meaning in the C-version and is ignored there. d = Decimal("Infinity") self.assertEqual(d.as_tuple(), (0, (0,), 'F') ) @@ -2012,12 +2013,14 @@ class UsabilityTest(unittest.TestCase): d = Decimal( (1, (), 'n') ) self.assertEqual(d.as_tuple(), (1, (), 'n') ) - # XXX coefficient in infinity should raise an error - if self.decimal == P: - d = Decimal( (0, (4, 5, 3, 4), 'F') ) - self.assertEqual(d.as_tuple(), (0, (0,), 'F')) - d = Decimal( (1, (0, 2, 7, 1), 'F') ) - self.assertEqual(d.as_tuple(), (1, (0,), 'F')) + # For infinities, decimal.py has always silently accepted any + # coefficient tuple. + d = Decimal( (0, (0,), 'F') ) + self.assertEqual(d.as_tuple(), (0, (0,), 'F')) + d = Decimal( (0, (4, 5, 3, 4), 'F') ) + self.assertEqual(d.as_tuple(), (0, (0,), 'F')) + d = Decimal( (1, (0, 2, 7, 1), 'F') ) + self.assertEqual(d.as_tuple(), (1, (0,), 'F')) def test_subclassing(self): # Different behaviours when subclassing Decimal diff --git a/Misc/NEWS b/Misc/NEWS index 9a301c31ddf..bed62b67d25 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -17,6 +17,10 @@ Core and Builtins Library ------- +- Issue #15882: Change _decimal to accept any coefficient tuple when + constructing infinities. This is done for backwards compatibility + with decimal.py: Infinity coefficients are undefined in _decimal + (in accordance with the specification). What's New in Python 3.3.0 Release Candidate 2? =============================================== diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 15c64e215d7..996f9da17be 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -2364,6 +2364,7 @@ dectuple_as_str(PyObject *dectuple) long sign, l; mpd_ssize_t exp = 0; Py_ssize_t i, mem, tsize; + int is_infinite = 0; int n; assert(PyTuple_Check(dectuple)); @@ -2399,6 +2400,7 @@ dectuple_as_str(PyObject *dectuple) /* special */ if (PyUnicode_CompareWithASCIIString(tmp, "F") == 0) { strcat(sign_special, "Inf"); + is_infinite = 1; } else if (PyUnicode_CompareWithASCIIString(tmp, "n") == 0) { strcat(sign_special, "NaN"); @@ -2470,6 +2472,11 @@ dectuple_as_str(PyObject *dectuple) "coefficient must be a tuple of digits"); goto error; } + if (is_infinite) { + /* accept but ignore any well-formed coefficient for compatibility + with decimal.py */ + continue; + } *cp++ = (char)l + '0'; } *cp = '\0';