This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients vstinner
Date 2020-04-20.21:53:09
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1587419589.68.0.186666450831.issue40346@roundup.psfhosted.org>
In-reply-to
Content
The random.Random class has a strange inheritance which is something uncommon in Python: it inherits from _random.Random which a concrete Mersenne Twister PRNG.

When a class inherit it, like random.SystemRandom, it should carefully override the right method.

I would expect to have something like a base class with abstract methods which raise NotImplementedError, and a concrete implementation which inherits from the base class and the Mersenne Twister C implementation.

A concrete issue is the how subclass handle the newly added randbytes() method:
https://bugs.python.org/issue40286#msg366860

The base class should implement randbytes() using getrandbits(), and the Mersenne Twister would override randbytes() with its fast implementation.

It would avoid the need for such method:

    def __init_subclass__(cls, /, **kwargs):
        """Control how subclasses generate random integers.

        The algorithm a subclass can use depends on the random() and/or
        getrandbits() implementation available to it and determines
        whether it can generate random integers from arbitrarily large
        ranges.
        """

        for c in cls.__mro__:
            if '_randbelow' in c.__dict__:
                # just inherit it
                break
            if 'getrandbits' in c.__dict__:
                cls._randbelow = cls._randbelow_with_getrandbits
                break
            if 'random' in c.__dict__:
                cls._randbelow = cls._randbelow_without_getrandbits
                break

It would also be nice if the base class would support a RNG which only produce bytes, like SystemRandom with os.urandom() and implement getrandbits() from that.


I also had concerns with the implementation of bpo-40282 "Allow random.getrandbits(0)":
https://github.com/python/cpython/pull/19539#pullrequestreview-393728231


It's maybe time to fix the class hierarchy.
History
Date User Action Args
2020-04-20 21:53:09vstinnersetrecipients: + vstinner
2020-04-20 21:53:09vstinnersetmessageid: <1587419589.68.0.186666450831.issue40346@roundup.psfhosted.org>
2020-04-20 21:53:09vstinnerlinkissue40346 messages
2020-04-20 21:53:09vstinnercreate