Allow any object as an argument for random.seed

This commit is contained in:
jfh
2021-11-04 15:23:06 +02:00
parent aa00fe9c64
commit 05c4fcf934
2 changed files with 11 additions and 10 deletions

View File

@@ -40,8 +40,6 @@ class TestBasicOps:
self.gen.setstate(state) # should regenerate the same sequence
self.assertEqual(randseq, self.randomlist(N))
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_seedargs(self):
# Seed value with a negative hash.
class MySeed(object):
@@ -55,8 +53,6 @@ class TestBasicOps:
self.assertRaises(TypeError, self.gen.seed, 1, 2, 3, 4)
self.assertRaises(TypeError, type(self.gen), [])
# TODO: RUSTPYTHON Success for SystemRandom, failure for MersenneTwister
@unittest.skip
@unittest.mock.patch('random._urandom') # os.urandom
def test_seed_when_randomness_source_not_found(self, urandom_mock):
# Random.seed() uses time.time() when an operating system specific
@@ -887,7 +883,7 @@ class TestDistributions(unittest.TestCase):
returned_value = random.gammavariate(1.1, 2.3)
self.assertAlmostEqual(returned_value, 2.53)
# TODO: RUSTPYTHON
# TODO: RUSTPYTHON assertAlmostEqual failure.
@unittest.expectedFailure
@unittest.mock.patch('random.Random.random')
def test_gammavariate_alpha_equal_one(self, random_mock):
@@ -900,7 +896,7 @@ class TestDistributions(unittest.TestCase):
returned_value = random.gammavariate(1.0, 3.14)
self.assertAlmostEqual(returned_value, 1.877208182372648)
# TODO: RUSTPYTHON
# TODO: RUSTPYTHON assertAlmostEqual failure.
@unittest.expectedFailure
@unittest.mock.patch('random.Random.random')
def test_gammavariate_alpha_equal_one_equals_expovariate(self, random_mock):

View File

@@ -6,7 +6,7 @@ pub(crate) use _random::make_module;
mod _random {
use crate::common::lock::PyMutex;
use crate::vm::{
builtins::{PyIntRef, PyTypeRef},
builtins::{PyInt, PyTypeRef},
function::OptionalOption,
types::Constructor,
PyObjectRef, PyResult, PyValue, VirtualMachine,
@@ -85,13 +85,17 @@ mod _random {
mt19937::gen_res53(&mut *rng)
}
// TODO: n can be a float, str, bytes, or bytearray
#[pymethod]
fn seed(&self, n: OptionalOption<PyIntRef>) {
fn seed(&self, n: OptionalOption<PyObjectRef>, vm: &VirtualMachine) -> PyResult<()> {
let new_rng = match n.flatten() {
None => PyRng::default(),
Some(n) => {
let (_, mut key) = n.as_bigint().abs().to_u32_digits();
// Fallback to using hash if object isn't Int-like.
let (_, mut key) = match n.downcast::<PyInt>() {
Ok(n) => n.as_bigint().abs(),
Err(obj) => BigInt::from(obj.hash(vm)?).abs(),
}
.to_u32_digits();
if cfg!(target_endian = "big") {
key.reverse();
}
@@ -101,6 +105,7 @@ mod _random {
};
*self.rng.lock() = new_rng;
Ok(())
}
#[pymethod]