diff options
author | Stefan Krah <skrah@bytereef.org> | 2020-02-21 00:52:47 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-21 00:52:47 (GMT) |
commit | 90930e65455f60216f09d175586139242dbba260 (patch) | |
tree | 04d12963cae3cfd86430ca5a0480727c1e70439c /Lib/test/test_decimal.py | |
parent | 6c444d0dab8f06cf304263b34beb299101cef3de (diff) | |
download | cpython-90930e65455f60216f09d175586139242dbba260.zip cpython-90930e65455f60216f09d175586139242dbba260.tar.gz cpython-90930e65455f60216f09d175586139242dbba260.tar.bz2 |
bpo-39576: Prevent memory error for overly optimistic precisions (GH-18581)
Diffstat (limited to 'Lib/test/test_decimal.py')
-rw-r--r-- | Lib/test/test_decimal.py | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index fe0cfc7..f1abd2a 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -5476,6 +5476,41 @@ class CWhitebox(unittest.TestCase): self.assertEqual(Decimal.from_float(cls(101.1)), Decimal.from_float(101.1)) + def test_maxcontext_exact_arith(self): + + # Make sure that exact operations do not raise MemoryError due + # to huge intermediate values when the context precision is very + # large. + + # The following functions fill the available precision and are + # therefore not suitable for large precisions (by design of the + # specification). + MaxContextSkip = ['logical_invert', 'next_minus', 'next_plus', + 'logical_and', 'logical_or', 'logical_xor', + 'next_toward', 'rotate', 'shift'] + + Decimal = C.Decimal + Context = C.Context + localcontext = C.localcontext + + # Here only some functions that are likely candidates for triggering a + # MemoryError are tested. deccheck.py has an exhaustive test. + maxcontext = Context(prec=C.MAX_PREC, Emin=C.MIN_EMIN, Emax=C.MAX_EMAX) + with localcontext(maxcontext): + self.assertEqual(Decimal(0).exp(), 1) + self.assertEqual(Decimal(1).ln(), 0) + self.assertEqual(Decimal(1).log10(), 0) + self.assertEqual(Decimal(10**2).log10(), 2) + self.assertEqual(Decimal(10**223).log10(), 223) + self.assertEqual(Decimal(10**19).logb(), 19) + self.assertEqual(Decimal(4).sqrt(), 2) + self.assertEqual(Decimal("40E9").sqrt(), Decimal('2.0E+5')) + self.assertEqual(divmod(Decimal(10), 3), (3, 1)) + self.assertEqual(Decimal(10) // 3, 3) + self.assertEqual(Decimal(4) / 2, 2) + self.assertEqual(Decimal(400) ** -1, Decimal('0.0025')) + + @requires_docstrings @unittest.skipUnless(C, "test requires C version") class SignatureTest(unittest.TestCase): |