Skip to content

Commit

Permalink
[3.6] bpo-29960 _random.Random corrupted on exception in setstate(). … (
Browse files Browse the repository at this point in the history
#1287)

(cherry picked from commit 9616a82)
  • Loading branch information
Mariatta committed May 27, 2017
1 parent b52c68a commit 94d8261
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 1 deletion.
5 changes: 5 additions & 0 deletions Lib/test/test_random.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ def test_setstate_first_arg(self):
self.assertRaises(ValueError, self.gen.setstate, (1, None, None))

def test_setstate_middle_arg(self):
start_state = self.gen.getstate()
# Wrong type, s/b tuple
self.assertRaises(TypeError, self.gen.setstate, (2, None, None))
# Wrong length, s/b 625
Expand All @@ -440,6 +441,10 @@ def test_setstate_middle_arg(self):
self.gen.setstate((2, (1,)*624+(625,), None))
with self.assertRaises((ValueError, OverflowError)):
self.gen.setstate((2, (1,)*624+(-1,), None))
# Failed calls to setstate() should not have changed the state.
bits100 = self.gen.getrandbits(100)
self.gen.setstate(start_state)
self.assertEqual(self.gen.getrandbits(100), bits100)

# Little trick to make "tuple(x % (2**32) for x in internalstate)"
# raise ValueError. I cannot think of a simple way to achieve this, so
Expand Down
1 change: 1 addition & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,7 @@ Milan Oberkirch
Pascal Oberndoerfer
Jeffrey Ollie
Adam Olsen
Bryan Olson
Grant Olson
Koray Oner
Piet van Oostrum
Expand Down
3 changes: 3 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ Core and Builtins
Library
-------

- bpo-29960: Preserve generator state when _random.Random.setstate()
raises an exception. Patch by Bryan Olson.

- bpo-30414: multiprocessing.Queue._feed background running
thread do not break from main loop on exception.

Expand Down
5 changes: 4 additions & 1 deletion Modules/_randommodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ random_setstate(RandomObject *self, PyObject *state)
int i;
unsigned long element;
long index;
uint32_t new_state[N];

if (!PyTuple_Check(state)) {
PyErr_SetString(PyExc_TypeError,
Expand All @@ -364,7 +365,7 @@ random_setstate(RandomObject *self, PyObject *state)
element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i));
if (element == (unsigned long)-1 && PyErr_Occurred())
return NULL;
self->state[i] = (uint32_t)element;
new_state[i] = (uint32_t)element;
}

index = PyLong_AsLong(PyTuple_GET_ITEM(state, i));
Expand All @@ -375,6 +376,8 @@ random_setstate(RandomObject *self, PyObject *state)
return NULL;
}
self->index = (int)index;
for (i = 0; i < N; i++)
self->state[i] = new_state[i];

Py_INCREF(Py_None);
return Py_None;
Expand Down

0 comments on commit 94d8261

Please sign in to comment.