Commit f763a728 authored by Raymond Hettinger's avatar Raymond Hettinger

Document which part of the random module module are guaranteed.

parent 435cb0f2
......@@ -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.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment