Document which part of the random module module are guaranteed.
This commit is contained in:
parent
435cb0f233
commit
f763a728ad
|
@ -51,18 +51,23 @@ from sources provided by the operating system.
|
|||
Bookkeeping functions:
|
||||
|
||||
|
||||
.. function:: seed([x])
|
||||
.. function:: seed([x], version=2)
|
||||
|
||||
Initialize the basic random number generator. Optional argument *x* can be any
|
||||
:term:`hashable` object. If *x* is omitted or ``None``, current system time is used;
|
||||
current system time is also used to initialize the generator when the module is
|
||||
first imported. If randomness sources are provided by the operating system,
|
||||
they are used instead of the system time (see the :func:`os.urandom` function
|
||||
for details on availability).
|
||||
Initialize the random number generator.
|
||||
|
||||
If *x* is not ``None`` or an int, ``hash(x)`` is used instead. If *x* is an
|
||||
int, *x* is used directly.
|
||||
If *x* is omitted or ``None``, the current system time is used. If
|
||||
randomness sources are provided by the operating system, they are used
|
||||
instead of the system time (see the :func:`os.urandom` function for details
|
||||
on availability).
|
||||
|
||||
If *x* is an int, it is used directly.
|
||||
|
||||
With version 2 (the default), a :class:`str`, :class:`bytes`, or :class:`bytearray`
|
||||
object gets converted to a :class:`int` and all of its bits are used. With version 1,
|
||||
the :func:`hash` of *x* is used instead.
|
||||
|
||||
.. versionchanged:: 3.2
|
||||
Moved to the version 2 scheme which uses all of the bits in a string seed.
|
||||
|
||||
.. function:: getstate()
|
||||
|
||||
|
|
|
@ -91,13 +91,17 @@ class Random(_random.Random):
|
|||
self.seed(x)
|
||||
self.gauss_next = None
|
||||
|
||||
def seed(self, a=None):
|
||||
def seed(self, a=None, version=2):
|
||||
"""Initialize internal state from hashable object.
|
||||
|
||||
None or no argument seeds from current time or from an operating
|
||||
system specific randomness source if available.
|
||||
|
||||
If a is not None or an int, hash(a) is used instead.
|
||||
For version 2 (the default), all of the bits are used if a is a str,
|
||||
bytes, or bytearray. For version 1, the hash() of a is used instead.
|
||||
|
||||
If a is an int, all bits are used.
|
||||
|
||||
"""
|
||||
|
||||
if a is None:
|
||||
|
@ -107,6 +111,11 @@ class Random(_random.Random):
|
|||
import time
|
||||
a = int(time.time() * 256) # use fractional seconds
|
||||
|
||||
if version == 2 and isinstance(a, (str, bytes, bytearray)):
|
||||
if isinstance(a, str):
|
||||
a = a.encode("utf8")
|
||||
a = int(_hexlify(a), 16)
|
||||
|
||||
super().seed(a)
|
||||
self.gauss_next = None
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ class TestBasicOps(unittest.TestCase):
|
|||
self.gen.seed(arg)
|
||||
for arg in [list(range(3)), dict(one=1)]:
|
||||
self.assertRaises(TypeError, self.gen.seed, arg)
|
||||
self.assertRaises(TypeError, self.gen.seed, 1, 2)
|
||||
self.assertRaises(TypeError, self.gen.seed, 1, 2, 3, 4)
|
||||
self.assertRaises(TypeError, type(self.gen), [])
|
||||
|
||||
def test_sample(self):
|
||||
|
@ -223,6 +223,21 @@ class SystemRandom_TestBasicOps(TestBasicOps):
|
|||
class MersenneTwister_TestBasicOps(TestBasicOps):
|
||||
gen = random.Random()
|
||||
|
||||
def test_guaranteed_stable(self):
|
||||
# These sequences are guaranteed to stay the same across versions of python
|
||||
self.gen.seed(3456147, version=1)
|
||||
self.assertEqual([self.gen.random().hex() for i in range(4)],
|
||||
['0x1.ac362300d90d2p-1', '0x1.9d16f74365005p-1',
|
||||
'0x1.1ebb4352e4c4dp-1', '0x1.1a7422abf9c11p-1'])
|
||||
self.gen.seed("the quick brown fox", version=1)
|
||||
self.assertEqual([self.gen.random().hex() for i in range(4)],
|
||||
['0x1.9ee265c177cdep-2', '0x1.bad51092e3c25p-1',
|
||||
'0x1.85ff833f71576p-1', '0x1.87efb37462927p-1'])
|
||||
self.gen.seed("the quick brown fox", version=2)
|
||||
self.assertEqual([self.gen.random().hex() for i in range(4)],
|
||||
['0x1.1294009b9eda4p-2', '0x1.2ff96171b0010p-1',
|
||||
'0x1.459e0989bd8e0p-5', '0x1.8b5f55892ddcbp-1'])
|
||||
|
||||
def test_setstate_first_arg(self):
|
||||
self.assertRaises(ValueError, self.gen.setstate, (1, None, None))
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@ Library
|
|||
* Document which parts of the module are guaranteed to stay the same
|
||||
across versions and which parts are subject to change.
|
||||
|
||||
* Update the seed() method to use all of the bits in a string
|
||||
instead of just the hash value.
|
||||
|
||||
- collections.OrderedDict now supports a new method for repositioning
|
||||
keys to either end.
|
||||
|
||||
|
|
Loading…
Reference in New Issue