bpo-33203: Ensure random.choice always raises IndexError on empty seq… · python/cpython@e25af93 (original) (raw)

3 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -241,6 +241,8 @@ def _randbelow(self, n, int=int, maxsize=1<<BPF, type=type,
241 241 "enough bits to choose from a population range this large.\n"
242 242 "To remove the range limitation, add a getrandbits() method.")
243 243 return int(random() * n)
244 +if n == 0:
245 +raise ValueError("Boundary cannot be zero")
244 246 rem = maxsize % n
245 247 limit = (maxsize - rem) / maxsize # int(limit * maxsize) % n == 0
246 248 r = random()
Original file line number Diff line number Diff line change
@@ -644,7 +644,10 @@ def test_randbelow_overridden_random(self, random_mock):
644 644 # Population range too large (n >= maxsize)
645 645 self.gen._randbelow(maxsize+1, maxsize = maxsize)
646 646 self.gen._randbelow(5640, maxsize = maxsize)
647 -
647 +# issue 33203: test that _randbelow raises ValueError on
648 +# n == 0 also in its getrandbits-independent branch.
649 +with self.assertRaises(ValueError):
650 +self.gen._randbelow(0, maxsize=maxsize)
648 651 # This might be going too far to test a single line, but because of our
649 652 # noble aim of achieving 100% test coverage we need to write a case in
650 653 # which the following line in Random._randbelow() gets executed:
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
1 +``random.Random.choice()`` now raises ``IndexError`` for empty sequences
2 +consistently even when called from subclasses without a ``getrandbits()``
3 +implementation.