[Python-ideas] Globally configurable random number generation

Andrew Barnert abarnert at yahoo.com
Tue Sep 15 06:03:05 CEST 2015

On Sep 14, 2015, at 20:22, Nick Coghlan <ncoghlan at gmail.com> wrote:
>> On 15 September 2015 at 12:30, Random832 <random832 at fastmail.com> wrote:
>> Nick Coghlan <ncoghlan at gmail.com> writes:
>>> Compared to my original proposal, the seedable MT RNG retains the
>>> random.Random name, so any code already using explicit instances is
>>> entirely unaffected by the proposed change.
>> So, if you use random.Random() without seeding, you still get "MT seeded
>> from os.urandom"?
> Yes, with the revised proposal, only the module level functions would
> change their behaviour to use a CSPRNG by default. If you trawl the
> various cryptographically unsound password generation recipes, they're
> almost all using the module level functions, so changing the meaning
> of random.Random itself would add a lot of additional pain for next to
> no gain.

That definitely makes things simpler. The only part of my set_default_instance patch that was at all tricky was how to make sure Random instances worked the same as top-level functions, but still providing a way to explicitly select one (hence renaming the base class to DeterministicRandom, making a new subclass UnsafeRandom that subclasses it and added the warning, and making both Random and the top-level functions point at that). If we don't need that, then your simpler solution makes more sense.

Also, while I'm not 100% sold on the auto-switching and the delegate-at-call-time wrappers, I'll play with them and see, and if they do work, then you're definitely right that your second version does solve your problem with my proposal, so it doesn't matter whether your first version did anymore.

First, on delegating top-level function: have you tested the performance? Is MT so slow that an extra lookup and function call don't matter?

One quick thought on auto-switching vs. explicitly setting the instance before any functions have been called: if I get you to install a plugin that calls random.seed(), I've now changed your app to use seeded random numbers. And it might even still pass security tests, because it doesn't switch until someone hits some API that activates the plugin. Is that a realistic danger for any realistic apps? If so, doesn't that potentially make 3.6 more dangerous than 3.5?

For another: I still think we should be getting people to explicitly use seeded_random or system_random (or seedless_random, if they need speed as well as "probably secure") or explicit class instances (which are a bigger change, but more backward compatible once you've made it) as often as possible, even if random does eventually turn into seedless_random. The fact that many apps will never actually issue a deprecation warning or any other signal that anything is changing may be leaning over too far toward convenience. I realize the benefit of having books and course materials written for 3.4 continue to work in 3.8, but really, if those books are giving people bad ideas, removing any incentive for anyone to change the next edition may not be a good idea.

And finally: it _seems like_ people who want MT for simulation/game/science stuff will have a pretty easy time finding the migration path, but I'm having a really hard time coming up with a convincing argument. Does anyone have a handful of science guys they can hack up a system for and test them empirically? Because if you can establish that fact, I think the naysayers have very little reason left to say nay, and a consensus would surely be better than having that horribly contentious thread end with "too bad, overruled, the PEP has been accepted".

More information about the Python-ideas mailing list