diff --git a/Lib/random.py b/Lib/random.py index 7210f62b100..2530c39ac76 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -258,6 +258,10 @@ class Random(_random.Random): result[i] = pool[j] pool[j] = pool[n-i-1] # move non-selected item into vacancy else: + try: + n > 0 and (population[0], population[n//2], population[n-1]) + except (TypeError, KeyError): # handle sets and dictionaries + population = tuple(population) selected = {} for i in xrange(k): j = _int(random() * n) diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index c9103e8f87b..fbd418457a6 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -86,6 +86,16 @@ class TestBasicOps(unittest.TestCase): else: self.fail() + def test_sample_inputs(self): + # SF bug #801342 -- population can be any iterable defining __len__() + from sets import Set + self.gen.sample(Set(range(20)), 2) + self.gen.sample(range(20), 2) + self.gen.sample(xrange(20), 2) + self.gen.sample(dict.fromkeys('abcdefghijklmnopqrst'), 2) + self.gen.sample(str('abcdefghijklmnopqrst'), 2) + self.gen.sample(tuple('abcdefghijklmnopqrst'), 2) + def test_gauss(self): # 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