]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-40325: Deprecate set object support in random.sample() (GH-19591)
authorRaymond Hettinger <rhettinger@users.noreply.github.com>
Sun, 19 Apr 2020 07:36:42 +0000 (00:36 -0700)
committerGitHub <noreply@github.com>
Sun, 19 Apr 2020 07:36:42 +0000 (00:36 -0700)
Doc/library/random.rst
Lib/random.py
Lib/test/test_random.py
Misc/NEWS.d/next/Library/2020-04-18-19-40-00.bpo-40325.KWSvix.rst [new file with mode: 0644]

index 9964af46b2efee2b43a858a8837ba5b4b26a555a..82e900d3a20ab08d0116f76bd56464aeff8f54fe 100644 (file)
@@ -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
 -------------------------
 
index 3243938282b50e39a768316f8ec153c08d33c097..f1df18d5c187b8ef584319047dcd0a01039f388e 100644 (file)
@@ -367,9 +367,12 @@ class Random(_random.Random):
         # 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:
index 50d4e94ca22f8965bc677106f273b1316a9b32d4..42c68dd1c24422b6b379bb700edb890c24c1c2d8 100644 (file)
@@ -147,7 +147,6 @@ class TestBasicOps:
 
     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 @@ class TestBasicOps:
     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 (file)
index 0000000..3df5fad
--- /dev/null
@@ -0,0 +1 @@
+Deprecated support for set objects in random.sample().