STINNER Victor <vstin...@python.org> added the comment:

> Making it easy to create subclasses was never a goal regardless.

It's clearly advertised at the beginning of the documentation:

"Class Random can also be subclassed if you want to use a different basic 
generator of your own devising: (...)"

Do you mean that the documentation is wrong and users must not subclass 
random.Random?


> If that makes any method currently in use slower, it's not worth it.

I don't think that my PR 19631 has any impact on random.Random and 
random.SystemRandom performances. Only new 3rd party classes which will be 
written to inherit from the *new* random.BaseRandom loose the gauss() 
optimization.

It would be possible to keep the optimization, but it would make class 
inheritance more complex: subclasses would have to call seed(), getstate() and 
setstate() methods of BaseRandom. Moreover, I dislike that the base class is 
not thread state. I prefer to keep it simple and correct.


> that reworking this doesn't solve any actual problem.

I changed the issue title to clarify my intent.

My intent is to ease the creation of subclasses. In Python 3.8, a subclass has 
to *override* 5 methods: getrandbits(), random(), seed(), getstate() and 
setstate().

With the proposed BaseRandom, a sublcass only has to *implement* *1* single 
method, getrandbits():

* random() and randbytes() are implemented with getrandbits() automatically
* seed(), getstate() and setstate() raise NotImplementedError, as done by 
SystemRandom currently. Obviously, you can override them if you want. But at 
least, you don't inherit the whole Mersenne Twister state by default.

The current problem is that Python 3.9 adds randbytes() which means that a 
class which inherit from random.Random now has to override not 5 but 6 methods: 
it now also has to override randbytes().

Raymond proposes to remove _random.Random.randbytes() C implementation and use 
instead a Python implementation which is 5x slower.

For me, it's surprising that if a subclass doesn't override all methods, it 
gets a Mersenne Twister implementation. See my msg366918 example. I would 
prefer a real base class with has no default implementation.

It doesn't prevent people to continue to inherit from random.Random: classes 
which inherit from random.Random continue to work.

Note: currently in my PR 19631, seed() has to be implemented since it's called 
by the constructor. I'm not sure if it's a good design or not.

----------
title: Redesign random.Random class inheritance -> Add random.BaseRandom to 
ease implementation of subclasses

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue40346>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to