[Python-checkins] bpo-42470: Do not warn on sequences which are also sets in random.sample() (GH-23665)

rhettinger webhook-mailer at python.org
Fri Dec 18 23:33:45 EST 2020


https://github.com/python/cpython/commit/1e27b57dbc8c1b758e37a531487813aef2d111ca
commit: 1e27b57dbc8c1b758e37a531487813aef2d111ca
branch: master
author: masklinn <github.com at masklinn.net>
committer: rhettinger <rhettinger at users.noreply.github.com>
date: 2020-12-18T20:33:36-08:00
summary:

bpo-42470: Do not warn on sequences which are also sets in random.sample() (GH-23665)

files:
A Misc/NEWS.d/next/Library/2020-12-06-12-00-00.bpo-42470.iqtC4L.rst
M Lib/random.py
M Lib/test/test_random.py

diff --git a/Lib/random.py b/Lib/random.py
index 139e8a40bb272..66433baa8cc18 100644
--- a/Lib/random.py
+++ b/Lib/random.py
@@ -424,13 +424,14 @@ def sample(self, population, k, *, counts=None):
         # too many calls to _randbelow(), making them slower and
         # 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.  For dicts or sets, use sorted(d).")
+            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)
+            else:
+                raise TypeError("Population must be a sequence.  For dicts or sets, use sorted(d).")
         n = len(population)
         if counts is not None:
             cum_counts = list(_accumulate(counts))
diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py
index 0c1fdeec9915e..327bfa3bbda1b 100644
--- a/Lib/test/test_random.py
+++ b/Lib/test/test_random.py
@@ -11,7 +11,7 @@
 from math import log, exp, pi, fsum, sin, factorial
 from test import support
 from fractions import Fraction
-from collections import Counter
+from collections import abc, Counter
 
 class TestBasicOps:
     # Superclass with tests common to all generators.
@@ -163,6 +163,22 @@ def test_sample_on_sets(self):
             population = {10, 20, 30, 40, 50, 60, 70}
             self.gen.sample(population, k=5)
 
+    def test_sample_on_seqsets(self):
+        class SeqSet(abc.Sequence, abc.Set):
+            def __init__(self, items):
+                self._items = items
+
+            def __len__(self):
+                return len(self._items)
+
+            def __getitem__(self, index):
+                return self._items[index]
+
+        population = SeqSet([2, 4, 1, 3])
+        with warnings.catch_warnings():
+            warnings.simplefilter("error", DeprecationWarning)
+            self.gen.sample(population, k=2)
+
     def test_sample_with_counts(self):
         sample = self.gen.sample
 
diff --git a/Misc/NEWS.d/next/Library/2020-12-06-12-00-00.bpo-42470.iqtC4L.rst b/Misc/NEWS.d/next/Library/2020-12-06-12-00-00.bpo-42470.iqtC4L.rst
new file mode 100644
index 0000000000000..cd2edb65d7a6c
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-12-06-12-00-00.bpo-42470.iqtC4L.rst
@@ -0,0 +1 @@
+:func:`random.sample` no longer warns on a sequence which is also a set.



More information about the Python-checkins mailing list