summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/random.py5
-rw-r--r--Lib/test/test_random.py19
-rw-r--r--Misc/NEWS7
3 files changed, 30 insertions, 1 deletions
diff --git a/Lib/random.py b/Lib/random.py
index f502d1d..fe25642 100644
--- a/Lib/random.py
+++ b/Lib/random.py
@@ -116,7 +116,6 @@ class Random:
"""
self.seed(x)
- self.gauss_next = None
## -------------------- core generator -------------------
@@ -150,6 +149,8 @@ class Random:
a, z = divmod(a, 30322)
self._seed = int(x)+1, int(y)+1, int(z)+1
+ self.gauss_next = None
+
def random(self):
"""Get the next random number in the range [0.0, 1.0)."""
@@ -238,6 +239,8 @@ class Random:
# Zero is a poor seed, so substitute 1
self._seed = (x or 1, y or 1, z or 1)
+ self.gauss_next = None
+
def whseed(self, a=None):
"""Seed from hashable object's hash code.
diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py
new file mode 100644
index 0000000..d508c9f
--- /dev/null
+++ b/Lib/test/test_random.py
@@ -0,0 +1,19 @@
+import test_support
+import random
+
+# Ensure that the seed() method initializes all the hidden state. In
+# particular, through 2.2.1 it failed to reset a piece of state used by
+# (and only by) the .gauss() method.
+
+for seed in 1, 12, 123, 1234, 12345, 123456, 654321:
+ for seeder in random.seed, random.whseed:
+ seeder(seed)
+ x1 = random.random()
+ y1 = random.gauss(0, 1)
+
+ seeder(seed)
+ x2 = random.random()
+ y2 = random.gauss(0, 1)
+
+ test_support.vereq(x1, x2)
+ test_support.vereq(y1, y2)
diff --git a/Misc/NEWS b/Misc/NEWS
index 2fb6a83..803287e 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -104,6 +104,13 @@ Extension modules
Library
+- random.gauss() uses a piece of hidden state used by nothing else,
+ and the .seed() and .whseed() methods failed to reset it. In other
+ words, setting the seed didn't completely determine the sequence of
+ results produced by random.gauss(). It does now. Programs repeatedly
+ mixing calls to a seed method with calls to gauss() may see different
+ results now.
+
- The pickle.Pickler class grew a clear_memo() method to mimic that
provided by cPickle.Pickler.