Merge pull request #3412 from DimitrisJim/random_seed

Allow any object as an argument for random.seed
This commit is contained in:
Jeong YunWon
2021-11-06 14:24:22 +09:00
committed by GitHub
2 changed files with 23 additions and 34 deletions

View File

@@ -20,6 +20,8 @@ class TestBasicOps:
"""Helper function to make a list of random numbers"""
return [self.gen.random() for i in range(n)]
# TODO: RUSTPYTHON AttributeError: 'super' object has no attribute 'getstate'
@unittest.expectedFailure
def test_autoseed(self):
self.gen.seed()
state1 = self.gen.getstate()
@@ -28,7 +30,7 @@ class TestBasicOps:
state2 = self.gen.getstate()
self.assertNotEqual(state1, state2)
# TODO: RUSTPYTHON
# TODO: RUSTPYTHON AttributeError: 'super' object has no attribute 'getstate'
@unittest.expectedFailure
def test_saverestore(self):
N = 1000
@@ -254,6 +256,8 @@ class TestBasicOps:
self.assertEqual(x1, x2)
self.assertEqual(y1, y2)
# TODO: RUSTPYTHON AttributeError: 'super' object has no attribute 'getstate'
@unittest.expectedFailure
def test_pickling(self):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
state = pickle.dumps(self.gen, proto)
@@ -262,7 +266,7 @@ class TestBasicOps:
restoredseq = [newgen.random() for i in range(10)]
self.assertEqual(origseq, restoredseq)
# TODO: RUSTPYTHON
# TODO: RUSTPYTHON AttributeError: 'super' object has no attribute 'getstate'
@unittest.expectedFailure
def test_bug_1727780(self):
# verify that version-2-pickles can be loaded
@@ -412,26 +416,6 @@ class SystemRandom_TestBasicOps(TestBasicOps, unittest.TestCase):
class MersenneTwister_TestBasicOps(TestBasicOps, unittest.TestCase):
gen = random.Random()
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_autoseed(self):
super().test_autoseed()
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_seedargs(self):
super().test_seedargs()
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_pickling(self):
super().test_pickling()
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_seed_when_randomness_source_not_found(self):
super().test_seed_when_randomness_source_not_found()
def test_guaranteed_stable(self):
# These sequences are guaranteed to stay the same across versions of python
self.gen.seed(3456147, version=1)
@@ -502,7 +486,7 @@ class MersenneTwister_TestBasicOps(TestBasicOps, unittest.TestCase):
def test_setstate_first_arg(self):
self.assertRaises(ValueError, self.gen.setstate, (1, None, None))
# TODO: RUSTPYTHON
# TODO: RUSTPYTHON AttributeError: 'super' object has no attribute 'getstate'
@unittest.expectedFailure
def test_setstate_middle_arg(self):
start_state = self.gen.getstate()
@@ -628,7 +612,7 @@ class MersenneTwister_TestBasicOps(TestBasicOps, unittest.TestCase):
self.assertEqual(set(range(start,stop)),
set([self.gen.randrange(start,stop) for i in range(100)]))
# TODO: RUSTPYTHON
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_genrandbits(self):
# Verify cross-platform repeatability
@@ -685,7 +669,7 @@ class MersenneTwister_TestBasicOps(TestBasicOps, unittest.TestCase):
self.assertEqual(k, numbits) # note the stronger assertion
self.assertTrue(2**k > n > 2**(k-1)) # note the stronger assertion
# TODO: RUSTPYTHON
# TODO: RUSTPYTHON AttributeError: 'Random' object has no attribute '_randbelow_without_getrandbits'
@unittest.expectedFailure
def test_randbelow_without_getrandbits(self):
# Random._randbelow() can only use random() when the built-in one
@@ -785,7 +769,7 @@ def gamma(z, sqrt2pi=(2.0*pi)**0.5):
])
class TestDistributions(unittest.TestCase):
# TODO: RUSTPYTHON
# TODO: RUSTPYTHON ValueError: math domain error
@unittest.expectedFailure
def test_zeroinputs(self):
# Verify that distributions can handle a series of zero inputs'
@@ -899,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):
@@ -912,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):
@@ -1004,7 +988,7 @@ class TestDistributions(unittest.TestCase):
class TestRandomSubclassing(unittest.TestCase):
# TODO: RUSTPYTHON
# TODO: RUSTPYTHON Unexpected keyword argument newarg
@unittest.expectedFailure
def test_random_subclass_with_kwargs(self):
# SF bug #1486663 -- this used to erroneously raise a TypeError
@@ -1013,7 +997,7 @@ class TestRandomSubclassing(unittest.TestCase):
random.Random.__init__(self)
Subclass(newarg=1)
# TODO: RUSTPYTHON
# TODO: RUSTPYTHON AssertionError: items in the second set but not the first.
@unittest.expectedFailure
def test_subclasses_overriding_methods(self):
# Subclasses with an overridden random, but only the original

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]