[pypy-commit] pypy py3.6: Leave internal state unchanged if _random.Random.setstate() raises an exception (bpo-29960)
rlamy
pypy.commits at gmail.com
Thu Sep 12 11:10:17 EDT 2019
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: py3.6
Changeset: r97463:2cbe9ff66003
Date: 2019-09-12 16:09 +0100
http://bitbucket.org/pypy/pypy/changeset/2cbe9ff66003/
Log: Leave internal state unchanged if _random.Random.setstate() raises
an exception (bpo-29960)
diff --git a/pypy/module/_random/interp_random.py b/pypy/module/_random/interp_random.py
--- a/pypy/module/_random/interp_random.py
+++ b/pypy/module/_random/interp_random.py
@@ -70,15 +70,17 @@
# independent of platfrom, since the below condition is only
# true on 32 bit platforms anyway
w_add = space.pow(space.newint(2), space.newint(32), space.w_None)
+ _state = [r_uint(0)] * rrandom.N
for i in range(rrandom.N):
w_item = space.getitem(w_state, space.newint(i))
if space.is_true(space.lt(w_item, w_zero)):
w_item = space.add(w_item, w_add)
- self._rnd.state[i] = space.uint_w(w_item)
+ _state[i] = space.uint_w(w_item)
w_item = space.getitem(w_state, space.newint(rrandom.N))
index = space.int_w(w_item)
if index < 0 or index > rrandom.N:
raise oefmt(space.w_ValueError, "invalid state")
+ self._rnd.state = _state
self._rnd.index = index
@unwrap_spec(k=int)
diff --git a/pypy/module/_random/test/test_random.py b/pypy/module/_random/test/test_random.py
--- a/pypy/module/_random/test/test_random.py
+++ b/pypy/module/_random/test/test_random.py
@@ -41,6 +41,18 @@
# does not crash
rnd1.setstate((-1, ) * 624 + (0, ))
+ def test_failed_setstate(self):
+ import _random
+ rnd = _random.Random()
+ rnd.seed()
+ start_state = rnd.getstate()
+ raises(TypeError, rnd.setstate, None)
+ raises(ValueError, rnd.setstate, (1, 2, 3))
+ raises(TypeError, rnd.setstate, ('a',)*624 + (1,))
+ raises(ValueError, rnd.setstate, (1,)*624 + (625,))
+ # None of these failed calls should have changed the state
+ assert rnd.getstate() == start_state
+
def test_state_repr(self):
# since app-level jumpahead salts with repr(state),
# it is important the repr is consistent with cpython
More information about the pypy-commit
mailing list