Search code examples
pythoncclassrandomcpython

Calling random in secrets module


I am trying to understand how the secrets module of Python works and which modules it calls when generating random numbers. I don’t have a lot of programming experience, so please stay with me.

In the secrets module, they call a specific class of the Random module called Systemrandom. The class Systemrandom is then named _sysrand and the function _randbelow of this class is called. Here is the relevant code from secrets:

from random import SystemRandom

_sysrand = SystemRandom()

randbits = _sysrand.getrandbits
choice = _sysrand.choice

def randbelow(exclusive_upper_bound):
    """Return a random int in the range [0, n)."""
    if exclusive_upper_bound <= 0:
        raise ValueError("Upper bound must be positive.")
    return _sysrand._randbelow(exclusive_upper_bound)

However, when I check the source code of random.py, I see that it actually defines two classes: Random and Systemrandom. I only see the randbelow function defined in the Random class (in lines 231-271). It does not appear in the Systemrandom class. The relevant code in random.py is:

class Random(_random.Random):
...
    [Define _randbelow] 
...
class SystemRandom(Random):
...

So suppose that you call the randbelow function from the secrets module. Then the computer will search the random module in the SystemRandom class. But there it will not find the _randbelow function. What am I missing?


Solution

  • Notice that there are two classes defined:

    class Random(_random.Random):
    

    and

    class SystemRandom(Random):
    

    SystemRandom is a subclass which inherits from Random.

    _randbelow is defined in the Random class.

    This means _randbelow can also be used in the subclass SystemRandom.

    We say that _randbelow is inherited from Random.