[Python-checkins] bpo-40325: Deprecate set object support in random.sample() (GH-19591)

Raymond Hettinger webhook-mailer at python.org
Sun Apr 19 03:36:52 EDT 2020


https://github.com/python/cpython/commit/4fe002045fcf40823154b709fef0948b2bc5e934
commit: 4fe002045fcf40823154b709fef0948b2bc5e934
branch: master
author: Raymond Hettinger <rhettinger at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2020-04-19T00:36:42-07:00
summary:

bpo-40325: Deprecate set object support in random.sample() (GH-19591)

files:
A Misc/NEWS.d/next/Library/2020-04-18-19-40-00.bpo-40325.KWSvix.rst
M Doc/library/random.rst
M Lib/random.py
M Lib/test/test_random.py

diff --git a/Doc/library/random.rst b/Doc/library/random.rst
index 9964af46b2efe..82e900d3a20ab 100644
--- a/Doc/library/random.rst
+++ b/Doc/library/random.rst
@@ -230,6 +230,13 @@ Functions for sequences
    If the sample size is larger than the population size, a :exc:`ValueError`
    is raised.
 
+   .. deprecated:: 3.9
+      In the future, the *population* must be a sequence.  Instances of
+      :class:`set` are no longer supported.  The set must first be converted
+      to a :class:`list` or :class:`tuple`, preferably in a deterministic
+      order so that the sample is reproducible.
+
+
 Real-valued distributions
 -------------------------
 
diff --git a/Lib/random.py b/Lib/random.py
index 3243938282b50..f1df18d5c187b 100644
--- a/Lib/random.py
+++ b/Lib/random.py
@@ -367,9 +367,12 @@ def sample(self, population, k):
         # causing them to eat more entropy than necessary.
 
         if isinstance(population, _Set):
+            _warn('Sampling from a set deprecated\n'
+                  'since Python 3.9 and will be removed in a subsequent version.',
+                  DeprecationWarning, 2)
             population = tuple(population)
         if not isinstance(population, _Sequence):
-            raise TypeError("Population must be a sequence or set.  For dicts, use list(d).")
+            raise TypeError("Population must be a sequence.  For dicts or sets, use sorted(d).")
         randbelow = self._randbelow
         n = len(population)
         if not 0 <= k <= n:
diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py
index 50d4e94ca22f8..42c68dd1c2442 100644
--- a/Lib/test/test_random.py
+++ b/Lib/test/test_random.py
@@ -147,7 +147,6 @@ def test_sample_distribution(self):
 
     def test_sample_inputs(self):
         # SF bug #801342 -- population can be any iterable defining __len__()
-        self.gen.sample(set(range(20)), 2)
         self.gen.sample(range(20), 2)
         self.gen.sample(range(20), 2)
         self.gen.sample(str('abcdefghijklmnopqrst'), 2)
@@ -156,6 +155,11 @@ def test_sample_inputs(self):
     def test_sample_on_dicts(self):
         self.assertRaises(TypeError, self.gen.sample, dict.fromkeys('abcdef'), 2)
 
+    def test_sample_on_sets(self):
+        with self.assertWarns(DeprecationWarning):
+            population = {10, 20, 30, 40, 50, 60, 70}
+            self.gen.sample(population, k=5)
+
     def test_choices(self):
         choices = self.gen.choices
         data = ['red', 'green', 'blue', 'yellow']
diff --git a/Misc/NEWS.d/next/Library/2020-04-18-19-40-00.bpo-40325.KWSvix.rst b/Misc/NEWS.d/next/Library/2020-04-18-19-40-00.bpo-40325.KWSvix.rst
new file mode 100644
index 0000000000000..3df5fade6676a
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-04-18-19-40-00.bpo-40325.KWSvix.rst
@@ -0,0 +1 @@
+Deprecated support for set objects in random.sample().



More information about the Python-checkins mailing list