Skip to content

Commit 1e27b57

Browse files
authored
bpo-42470: Do not warn on sequences which are also sets in random.sample() (GH-23665)
1 parent e009612 commit 1e27b57

File tree

3 files changed

+25
-7
lines changed

3 files changed

+25
-7
lines changed

Lib/random.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -424,13 +424,14 @@ def sample(self, population, k, *, counts=None):
424424
# too many calls to _randbelow(), making them slower and
425425
# causing them to eat more entropy than necessary.
426426

427-
if isinstance(population, _Set):
428-
_warn('Sampling from a set deprecated\n'
429-
'since Python 3.9 and will be removed in a subsequent version.',
430-
DeprecationWarning, 2)
431-
population = tuple(population)
432427
if not isinstance(population, _Sequence):
433-
raise TypeError("Population must be a sequence. For dicts or sets, use sorted(d).")
428+
if isinstance(population, _Set):
429+
_warn('Sampling from a set deprecated\n'
430+
'since Python 3.9 and will be removed in a subsequent version.',
431+
DeprecationWarning, 2)
432+
population = tuple(population)
433+
else:
434+
raise TypeError("Population must be a sequence. For dicts or sets, use sorted(d).")
434435
n = len(population)
435436
if counts is not None:
436437
cum_counts = list(_accumulate(counts))

Lib/test/test_random.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from math import log, exp, pi, fsum, sin, factorial
1212
from test import support
1313
from fractions import Fraction
14-
from collections import Counter
14+
from collections import abc, Counter
1515

1616
class TestBasicOps:
1717
# Superclass with tests common to all generators.
@@ -163,6 +163,22 @@ def test_sample_on_sets(self):
163163
population = {10, 20, 30, 40, 50, 60, 70}
164164
self.gen.sample(population, k=5)
165165

166+
def test_sample_on_seqsets(self):
167+
class SeqSet(abc.Sequence, abc.Set):
168+
def __init__(self, items):
169+
self._items = items
170+
171+
def __len__(self):
172+
return len(self._items)
173+
174+
def __getitem__(self, index):
175+
return self._items[index]
176+
177+
population = SeqSet([2, 4, 1, 3])
178+
with warnings.catch_warnings():
179+
warnings.simplefilter("error", DeprecationWarning)
180+
self.gen.sample(population, k=2)
181+
166182
def test_sample_with_counts(self):
167183
sample = self.gen.sample
168184

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:func:`random.sample` no longer warns on a sequence which is also a set.

0 commit comments

Comments
 (0)