Skip to content

Commit 05c4fcf

Browse files
committed
Allow any object as an argument for random.seed
1 parent aa00fe9 commit 05c4fcf

File tree

2 files changed

+11
-10
lines changed

2 files changed

+11
-10
lines changed

Lib/test/test_random.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ def test_saverestore(self):
4040
self.gen.setstate(state) # should regenerate the same sequence
4141
self.assertEqual(randseq, self.randomlist(N))
4242

43-
# TODO: RUSTPYTHON
44-
@unittest.expectedFailure
4543
def test_seedargs(self):
4644
# Seed value with a negative hash.
4745
class MySeed(object):
@@ -55,8 +53,6 @@ def __hash__(self):
5553
self.assertRaises(TypeError, self.gen.seed, 1, 2, 3, 4)
5654
self.assertRaises(TypeError, type(self.gen), [])
5755

58-
# TODO: RUSTPYTHON Success for SystemRandom, failure for MersenneTwister
59-
@unittest.skip
6056
@unittest.mock.patch('random._urandom') # os.urandom
6157
def test_seed_when_randomness_source_not_found(self, urandom_mock):
6258
# Random.seed() uses time.time() when an operating system specific
@@ -887,7 +883,7 @@ def test_gammavariate_alpha_greater_one(self, random_mock):
887883
returned_value = random.gammavariate(1.1, 2.3)
888884
self.assertAlmostEqual(returned_value, 2.53)
889885

890-
# TODO: RUSTPYTHON
886+
# TODO: RUSTPYTHON assertAlmostEqual failure.
891887
@unittest.expectedFailure
892888
@unittest.mock.patch('random.Random.random')
893889
def test_gammavariate_alpha_equal_one(self, random_mock):
@@ -900,7 +896,7 @@ def test_gammavariate_alpha_equal_one(self, random_mock):
900896
returned_value = random.gammavariate(1.0, 3.14)
901897
self.assertAlmostEqual(returned_value, 1.877208182372648)
902898

903-
# TODO: RUSTPYTHON
899+
# TODO: RUSTPYTHON assertAlmostEqual failure.
904900
@unittest.expectedFailure
905901
@unittest.mock.patch('random.Random.random')
906902
def test_gammavariate_alpha_equal_one_equals_expovariate(self, random_mock):

stdlib/src/random.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub(crate) use _random::make_module;
66
mod _random {
77
use crate::common::lock::PyMutex;
88
use crate::vm::{
9-
builtins::{PyIntRef, PyTypeRef},
9+
builtins::{PyInt, PyTypeRef},
1010
function::OptionalOption,
1111
types::Constructor,
1212
PyObjectRef, PyResult, PyValue, VirtualMachine,
@@ -85,13 +85,17 @@ mod _random {
8585
mt19937::gen_res53(&mut *rng)
8686
}
8787

88-
// TODO: n can be a float, str, bytes, or bytearray
8988
#[pymethod]
90-
fn seed(&self, n: OptionalOption<PyIntRef>) {
89+
fn seed(&self, n: OptionalOption<PyObjectRef>, vm: &VirtualMachine) -> PyResult<()> {
9190
let new_rng = match n.flatten() {
9291
None => PyRng::default(),
9392
Some(n) => {
94-
let (_, mut key) = n.as_bigint().abs().to_u32_digits();
93+
// Fallback to using hash if object isn't Int-like.
94+
let (_, mut key) = match n.downcast::<PyInt>() {
95+
Ok(n) => n.as_bigint().abs(),
96+
Err(obj) => BigInt::from(obj.hash(vm)?).abs(),
97+
}
98+
.to_u32_digits();
9599
if cfg!(target_endian = "big") {
96100
key.reverse();
97101
}
@@ -101,6 +105,7 @@ mod _random {
101105
};
102106

103107
*self.rng.lock() = new_rng;
108+
Ok(())
104109
}
105110

106111
#[pymethod]

0 commit comments

Comments
 (0)