Showing posts with label random. Show all posts
Showing posts with label random. Show all posts

Wednesday, 30 March 2016

Stateful Modules in Python

TIL that random.seed persists across imports, aka modules with state. (aka unintentional MonkeyPatching?)

Let's say we have "moduleA.py" (WARNING:  Do not rely on "random" for cryptographic purposes, use "os.urandom" instead)

import random


def get_random_numbers():
    s = random.sample(range(1000), 10)
    return s

And another file named "main.py"

from moduleA import get_random_numbers

import random


if __name__ == '__main__':
    for i in range(3):
        random.seed(1234)
        # do things with random
        
        # code from another module that uses random
        print(get_random_numbers())

The side effect may be obvious here (prints the same random numbers on each iteration).

Perhaps .seed should be treated as a runtime context? (instead of associating state with the module)

with random.seed(1337):
    _ = random.random()

To avoid this, one can seed random with os.urandom before each use.

import random
import os


def get_random_numbers():
    random.seed(os.urandom(256))
    s = random.sample(range(1000), 10)
    return s