Skip to content

Commit 70a071d

Browse files
authored
bpo-40465: Remove random module features deprecated in 3.9 (GH-25874)
1 parent 87109f4 commit 70a071d

File tree

4 files changed

+25
-64
lines changed

4 files changed

+25
-64
lines changed

Doc/library/random.rst

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ Bookkeeping functions
8686
.. versionchanged:: 3.2
8787
Moved to the version 2 scheme which uses all of the bits in a string seed.
8888

89-
.. deprecated:: 3.9
90-
In the future, the *seed* must be one of the following types:
89+
.. versionchanged:: 3.11
90+
The *seed* must be one of the following types:
9191
*NoneType*, :class:`int`, :class:`float`, :class:`str`,
9292
:class:`bytes`, or :class:`bytearray`.
9393

@@ -208,13 +208,10 @@ Functions for sequences
208208
Raises a :exc:`ValueError` if all weights are zero.
209209

210210

211-
.. function:: shuffle(x[, random])
211+
.. function:: shuffle(x)
212212

213213
Shuffle the sequence *x* in place.
214214

215-
The optional argument *random* is a 0-argument function returning a random
216-
float in [0.0, 1.0); by default, this is the function :func:`.random`.
217-
218215
To shuffle an immutable sequence and return a new shuffled list, use
219216
``sample(x, k=len(x))`` instead.
220217

@@ -230,8 +227,8 @@ Functions for sequences
230227

231228
.. function:: sample(population, k, *, counts=None)
232229

233-
Return a *k* length list of unique elements chosen from the population sequence
234-
or set. Used for random sampling without replacement.
230+
Return a *k* length list of unique elements chosen from the population
231+
sequence. Used for random sampling without replacement.
235232

236233
Returns a new list containing elements from the population while leaving the
237234
original population unchanged. The resulting list is in selection order so that
@@ -257,11 +254,10 @@ Functions for sequences
257254
.. versionchanged:: 3.9
258255
Added the *counts* parameter.
259256

260-
.. deprecated:: 3.9
261-
In the future, the *population* must be a sequence. Instances of
262-
:class:`set` are no longer supported. The set must first be converted
263-
to a :class:`list` or :class:`tuple`, preferably in a deterministic
264-
order so that the sample is reproducible.
257+
.. versionchanged:: 3.11
258+
259+
The *population* must be a sequence. Automatic conversion of sets
260+
to lists is longer supported.
265261

266262

267263
.. _real-valued-distributions:

Lib/random.py

Lines changed: 12 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,8 @@ def seed(self, a=None, version=2):
157157
a = int.from_bytes(a + _sha512(a).digest(), 'big')
158158

159159
elif not isinstance(a, (type(None), int, float, str, bytes, bytearray)):
160-
_warn('Seeding based on hashing is deprecated\n'
161-
'since Python 3.9 and will be removed in a subsequent '
162-
'version. The only \n'
163-
'supported seed types are: None, '
164-
'int, float, str, bytes, and bytearray.',
165-
DeprecationWarning, 2)
160+
raise TypeError('The only supported seed types are: None,\n'
161+
'int, float, str, bytes, and bytearray.')
166162

167163
super().seed(a)
168164
self.gauss_next = None
@@ -377,34 +373,17 @@ def choice(self, seq):
377373
# raises IndexError if seq is empty
378374
return seq[self._randbelow(len(seq))]
379375

380-
def shuffle(self, x, random=None):
381-
"""Shuffle list x in place, and return None.
382-
383-
Optional argument random is a 0-argument function returning a
384-
random float in [0.0, 1.0); if it is the default None, the
385-
standard random.random will be used.
386-
387-
"""
376+
def shuffle(self, x):
377+
"""Shuffle list x in place, and return None."""
388378

389-
if random is None:
390-
randbelow = self._randbelow
391-
for i in reversed(range(1, len(x))):
392-
# pick an element in x[:i+1] with which to exchange x[i]
393-
j = randbelow(i + 1)
394-
x[i], x[j] = x[j], x[i]
395-
else:
396-
_warn('The *random* parameter to shuffle() has been deprecated\n'
397-
'since Python 3.9 and will be removed in a subsequent '
398-
'version.',
399-
DeprecationWarning, 2)
400-
floor = _floor
401-
for i in reversed(range(1, len(x))):
402-
# pick an element in x[:i+1] with which to exchange x[i]
403-
j = floor(random() * (i + 1))
404-
x[i], x[j] = x[j], x[i]
379+
randbelow = self._randbelow
380+
for i in reversed(range(1, len(x))):
381+
# pick an element in x[:i+1] with which to exchange x[i]
382+
j = randbelow(i + 1)
383+
x[i], x[j] = x[j], x[i]
405384

406385
def sample(self, population, k, *, counts=None):
407-
"""Chooses k unique random elements from a population sequence or set.
386+
"""Chooses k unique random elements from a population sequence.
408387
409388
Returns a new list containing elements from the population while
410389
leaving the original population unchanged. The resulting list is
@@ -457,13 +436,8 @@ def sample(self, population, k, *, counts=None):
457436
# causing them to eat more entropy than necessary.
458437

459438
if not isinstance(population, _Sequence):
460-
if isinstance(population, _Set):
461-
_warn('Sampling from a set deprecated\n'
462-
'since Python 3.9 and will be removed in a subsequent version.',
463-
DeprecationWarning, 2)
464-
population = tuple(population)
465-
else:
466-
raise TypeError("Population must be a sequence. For dicts or sets, use sorted(d).")
439+
raise TypeError("Population must be a sequence. "
440+
"For dicts or sets, use sorted(d).")
467441
n = len(population)
468442
if counts is not None:
469443
cum_counts = list(_accumulate(counts))

Lib/test/test_random.py

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,11 @@ def __hash__(self):
4848
self.gen.seed(arg)
4949

5050
for arg in [1+2j, tuple('abc'), MySeed()]:
51-
with self.assertWarns(DeprecationWarning):
51+
with self.assertRaises(TypeError):
5252
self.gen.seed(arg)
5353

5454
for arg in [list(range(3)), dict(one=1)]:
55-
with self.assertWarns(DeprecationWarning):
56-
self.assertRaises(TypeError, self.gen.seed, arg)
55+
self.assertRaises(TypeError, self.gen.seed, arg)
5756
self.assertRaises(TypeError, self.gen.seed, 1, 2, 3, 4)
5857
self.assertRaises(TypeError, type(self.gen), [])
5958

@@ -105,15 +104,6 @@ def test_shuffle(self):
105104
self.assertTrue(lst != shuffled_lst)
106105
self.assertRaises(TypeError, shuffle, (1, 2, 3))
107106

108-
def test_shuffle_random_argument(self):
109-
# Test random argument to shuffle.
110-
shuffle = self.gen.shuffle
111-
mock_random = unittest.mock.Mock(return_value=0.5)
112-
seq = bytearray(b'abcdefghijk')
113-
with self.assertWarns(DeprecationWarning):
114-
shuffle(seq, mock_random)
115-
mock_random.assert_called_with()
116-
117107
def test_choice(self):
118108
choice = self.gen.choice
119109
with self.assertRaises(IndexError):
@@ -164,7 +154,7 @@ def test_sample_on_dicts(self):
164154
self.assertRaises(TypeError, self.gen.sample, dict.fromkeys('abcdef'), 2)
165155

166156
def test_sample_on_sets(self):
167-
with self.assertWarns(DeprecationWarning):
157+
with self.assertRaises(TypeError):
168158
population = {10, 20, 30, 40, 50, 60, 70}
169159
self.gen.sample(population, k=5)
170160

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Remove random module features deprecated in Python 3.9.

0 commit comments

Comments
 (0)