mirror of https://github.com/python/cpython
bpo-29960 _random.Random corrupted on exception in setstate(). (#1019)
This commit is contained in:
parent
1a5856bf92
commit
9616a82e78
|
@ -423,6 +423,7 @@ class MersenneTwister_TestBasicOps(TestBasicOps, unittest.TestCase):
|
||||||
self.assertRaises(ValueError, self.gen.setstate, (1, None, None))
|
self.assertRaises(ValueError, self.gen.setstate, (1, None, None))
|
||||||
|
|
||||||
def test_setstate_middle_arg(self):
|
def test_setstate_middle_arg(self):
|
||||||
|
start_state = self.gen.getstate()
|
||||||
# Wrong type, s/b tuple
|
# Wrong type, s/b tuple
|
||||||
self.assertRaises(TypeError, self.gen.setstate, (2, None, None))
|
self.assertRaises(TypeError, self.gen.setstate, (2, None, None))
|
||||||
# Wrong length, s/b 625
|
# Wrong length, s/b 625
|
||||||
|
@ -436,6 +437,10 @@ class MersenneTwister_TestBasicOps(TestBasicOps, unittest.TestCase):
|
||||||
self.gen.setstate((2, (1,)*624+(625,), None))
|
self.gen.setstate((2, (1,)*624+(625,), None))
|
||||||
with self.assertRaises((ValueError, OverflowError)):
|
with self.assertRaises((ValueError, OverflowError)):
|
||||||
self.gen.setstate((2, (1,)*624+(-1,), None))
|
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)"
|
# 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
|
# raise ValueError. I cannot think of a simple way to achieve this, so
|
||||||
|
|
|
@ -1110,6 +1110,7 @@ Milan Oberkirch
|
||||||
Pascal Oberndoerfer
|
Pascal Oberndoerfer
|
||||||
Jeffrey Ollie
|
Jeffrey Ollie
|
||||||
Adam Olsen
|
Adam Olsen
|
||||||
|
Bryan Olson
|
||||||
Grant Olson
|
Grant Olson
|
||||||
Koray Oner
|
Koray Oner
|
||||||
Piet van Oostrum
|
Piet van Oostrum
|
||||||
|
|
|
@ -317,6 +317,9 @@ Extension Modules
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- bpo-29960: Preserve generator state when _random.Random.setstate()
|
||||||
|
raises an exception. Patch by Bryan Olson.
|
||||||
|
|
||||||
- bpo-29802: Fixed reference counting in module-level struct functions when
|
- bpo-29802: Fixed reference counting in module-level struct functions when
|
||||||
pass arguments of wrong type.
|
pass arguments of wrong type.
|
||||||
|
|
||||||
|
|
|
@ -348,6 +348,7 @@ random_setstate(RandomObject *self, PyObject *state)
|
||||||
int i;
|
int i;
|
||||||
unsigned long element;
|
unsigned long element;
|
||||||
long index;
|
long index;
|
||||||
|
uint32_t new_state[N];
|
||||||
|
|
||||||
if (!PyTuple_Check(state)) {
|
if (!PyTuple_Check(state)) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
@ -364,7 +365,7 @@ random_setstate(RandomObject *self, PyObject *state)
|
||||||
element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i));
|
element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i));
|
||||||
if (element == (unsigned long)-1 && PyErr_Occurred())
|
if (element == (unsigned long)-1 && PyErr_Occurred())
|
||||||
return NULL;
|
return NULL;
|
||||||
self->state[i] = (uint32_t)element;
|
new_state[i] = (uint32_t)element;
|
||||||
}
|
}
|
||||||
|
|
||||||
index = PyLong_AsLong(PyTuple_GET_ITEM(state, i));
|
index = PyLong_AsLong(PyTuple_GET_ITEM(state, i));
|
||||||
|
@ -375,6 +376,8 @@ random_setstate(RandomObject *self, PyObject *state)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
self->index = (int)index;
|
self->index = (int)index;
|
||||||
|
for (i = 0; i < N; i++)
|
||||||
|
self->state[i] = new_state[i];
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue