]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-154001: Avoid division by zero in binomialvariate (GH-154004)
authorŁukasz <lukaszlapinski7@gmail.com>
Sun, 19 Jul 2026 06:06:09 +0000 (08:06 +0200)
committerGitHub <noreply@github.com>
Sun, 19 Jul 2026 06:06:09 +0000 (09:06 +0300)
Lib/random.py
Lib/test/test_random.py
Misc/NEWS.d/next/Library/2026-07-18-17-09-49.gh-issue-154001.3brrUv.rst [new file with mode: 0644]

index 4541267bab866a495670c0de88140d92a1a1fb49..7db761034509d37b6834f004d42b45d0ae5e43c4 100644 (file)
@@ -861,7 +861,11 @@ class Random(_random.Random):
             u = random()
             u -= 0.5
             us = 0.5 - _fabs(u)
-            k = _floor((2.0 * a / us + b) * u + c)
+            try:
+                k = _floor((2.0 * a / us + b) * u + c)
+            except ZeroDivisionError:
+                # Reject case where random() returned 0.0
+                continue
             if k < 0 or k > n:
                 continue
             v = random()
index dbd3b855f536a0d54533981474ca228b0e9c4990..8d093ab1b7014a4eb73fd81740e95ec8e2127349 100644 (file)
@@ -1082,6 +1082,14 @@ class TestDistributions(unittest.TestCase):
             self.assertIsInstance(result, int)
             self.assertIn(result, range(11))
 
+    def test_binomialvariate_btrs_random_zero(self):
+        for p, expected in ((0.25, 25), (0.75, 75)):
+            with self.subTest(p=p):
+                g = random.Random()
+                with unittest.mock.patch.object(
+                        g, 'random', side_effect=(0.0, 0.5, 0.5)):
+                    self.assertEqual(g.binomialvariate(100, p), expected)
+
     def test_constant(self):
         g = random.Random()
         N = 100
diff --git a/Misc/NEWS.d/next/Library/2026-07-18-17-09-49.gh-issue-154001.3brrUv.rst b/Misc/NEWS.d/next/Library/2026-07-18-17-09-49.gh-issue-154001.3brrUv.rst
new file mode 100644 (file)
index 0000000..ff019aa
--- /dev/null
@@ -0,0 +1,2 @@
+Fix :func:`random.binomialvariate` raising :exc:`ZeroDivisionError`
+when :func:`random.random` returns zero.