On Tue, Sep 15, 2015 at 8:40 PM, Nick Coghlan
I had to check out of the mega-threads, but I really don't like the outcome (unless this PEP is just the first of several competing proposals).
The random module provides a useful interface – a random() function and a large variety of derived functionality useful for statistics programming (e.g. uniform(), choice(), bivariate(), etc.). Many of these have significant mathematical finesse in their implementation. They are all accessing shared state that is kept in a global variable in the module, and that is a desirable feature (nobody wants to have to pass an extra variable just so you can share the state of the random number generator with some other code).
I don’t want to change this API and I don’t want to introduce deprecation warnings – the API is fine, and the warnings will be as ineffective as
On 16 September 2015 at 03:33, Guido van Rossum
wrote: the warnings in the documentation.
The proposed runtime warnings are just an additional harder to avoid nudge for folks that don't read the documentation, so I'd be OK with dropping them from the proposal.
Good, because I really don't want the warnings, nor the hack based on whether you call any of the seed/state-related methods.
However, it also occurs to me there may be a better solution to eliminating them than getting people to change their imports: add a "random.ensure_seedable()" API that flips the default instance to the deterministic RNG without triggering the warning.
For applications that genuinely want the determinism, warnings free 3.6+ compatibility would then look like:
if hasattr(random, "ensure_seedable"): random.ensure_seedable()
I don't believe that seedability is the only thing that matters. MT is also over an order of magnitude faster than os.urandom() or SystemRandom.
I am fine with adding more secure ways of generating random numbers. But we already have random.SystemRandom(), so there doesn’t seem to be a hurry?
How about we make one small change instead: a way to change the default instance used by the top-level functions in the random module. Say,
random.set_random_generator(<instance>)
That was my previous proposal. The problem with it is that it's much harder to test and support, as you have to allow for the global instance changing multiple times, and in multiple different directions.
Actually part of my proposal was a use_secure_random() that was also a one-way flag flip, just in the opposite direction. :-) With the proposal in the PEP, there's only a single idempotent change
that's possible: from the system RNG (used by default to eliminate the silent security failure) to the seedable RNG (needed for reproducibility).
I'd be much more comfortable if in 3.6 we only introduced a new way to generate secure random numbers that was as fast as MT. Once that has been in use for a few releases we may have a discussion about whether it's time to make it the default. Security isn't served well by panicky over-reaction. -- --Guido van Rossum (python.org/~guido)