diff --git a/Lib/random.py b/Lib/random.py index 91065b7..f32ff1c 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -94,6 +94,14 @@ class Random(_random.Random): self.seed(x) self.gauss_next = None + def __init_subclass__(cls): + # Only call self.getrandbits if the original random() builtin method + # has not been overridden or if a new getrandbits() was supplied. + if type(cls.random) is not _BuiltinMethodType and type(cls.getrandbits) is not _MethodType: + # There's an overridden random() method but no new getrandbits() method, + # so we can only use random() from here. + cls._randbelow = cls._randbelow_fallback + def seed(self, a=None, version=2): """Initialize internal state from hashable object. @@ -221,22 +229,18 @@ class Random(_random.Random): return self.randrange(a, b+1) - def _randbelow(self, n, int=int, maxsize=1<= n: - r = getrandbits(k) - return r - # There's an overridden random() method but no new getrandbits() method, - # so we can only use random() from here. + k = n.bit_length() # don't use (n-1) here because n can be 1 + r = getrandbits(k) # 0 <= r < 2**k + while r >= n: + r = getrandbits(k) + return r + + def _randbelow_fallback(self, n, int=int, maxsize=1<= maxsize: _warn("Underlying random() generator does not supply \n" "enough bits to choose from a population range this large.\n"