summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_decimal.py
diff options
context:
space:
mode:
authorStefan Krah <skrah@bytereef.org>2020-02-21 00:52:47 (GMT)
committerGitHub <noreply@github.com>2020-02-21 00:52:47 (GMT)
commit90930e65455f60216f09d175586139242dbba260 (patch)
tree04d12963cae3cfd86430ca5a0480727c1e70439c /Lib/test/test_decimal.py
parent6c444d0dab8f06cf304263b34beb299101cef3de (diff)
downloadcpython-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.py35
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):