diff -r b295b2286697 Lib/random.py --- a/Lib/random.py Wed Jul 01 11:29:34 2015 -0400 +++ b/Lib/random.py Thu Jul 02 13:32:27 2015 -0400 @@ -824,6 +824,16 @@ x = long(_hexlify(_urandom(bytes)), 16) return x >> (bytes * 8 - k) # trim excess bits + def randrange(self, start, stop=None, step=1): + """Choose a random item from range(start, stop[, step]). + + This fixes the problem with randint() which includes the + endpoint; in Python this is usually not what you want. + + """ + # http://bugs.python.org/issue23974 + return super(SystemRandom, self).randrange(start, stop, step, _maxwidth=0) + def _stub(self, *args, **kwds): "Stub method. Not used for a system random number generator." return None diff -r b295b2286697 Lib/test/test_random.py --- a/Lib/test/test_random.py Wed Jul 01 11:29:34 2015 -0400 +++ b/Lib/test/test_random.py Thu Jul 02 13:32:27 2015 -0400 @@ -262,6 +262,13 @@ self.assertEqual(set(range(start,stop)), set([self.gen.randrange(start,stop) for i in xrange(100)])) + def test_randrange_bias(self): + # From http://bugs.python.org/issue23974: + # Given 1000 random ints, approx. 500 will be odd if there's no bias, + # or 333 if this issue is present. 417 is halfway between the two. + span = 2**53 * 2//3 + self.assertGreater(sum(self.gen.randrange(span) & 1 for i in xrange(1000)), 417) + def test_genrandbits(self): # Verify ranges for k in xrange(1, 1000):