Index: Lib/random.py =================================================================== --- Lib/random.py (revision 58178) +++ Lib/random.py (working copy) @@ -83,7 +83,7 @@ """ - VERSION = 2 # used by getstate/setstate + VERSION = 3 # used by getstate/setstate def __init__(self, x=None): """Initialize an instance. @@ -120,9 +120,20 @@ def setstate(self, state): """Restore internal state from object returned by getstate().""" version = state[0] - if version == 2: + if version == 3: version, internalstate, self.gauss_next = state super(Random, self).setstate(internalstate) + elif version == 2: + version, internalstate, self.gauss_next = state + # In version 2, the state was saved as signed ints, which causes + # inconsistencies between 32/64-bit systems. The state is + # really unsigned 32-bit ints, so we convert negative ints from + # version 2 to positive longs for version 3. + try: + internalstate = tuple( long(x) % (2**32) for x in internalstate ) + except ValueError, e: + raise TypeError, e + super(Random, self).setstate(internalstate) else: raise ValueError("state with version %s passed to " "Random.setstate() of version %s" % Index: Modules/_randommodule.c =================================================================== --- Modules/_randommodule.c (revision 58178) +++ Modules/_randommodule.c (working copy) @@ -319,12 +319,12 @@ if (state == NULL) return NULL; for (i=0; istate[i])); + element = PyLong_FromUnsignedLong(self->state[i]); if (element == NULL) goto Fail; PyTuple_SET_ITEM(state, i, element); } - element = PyInt_FromLong((long)(self->index)); + element = PyLong_FromLong((long)(self->index)); if (element == NULL) goto Fail; PyTuple_SET_ITEM(state, i, element); @@ -339,7 +339,8 @@ random_setstate(RandomObject *self, PyObject *state) { int i; - long element; + unsigned long element; + long index; if (!PyTuple_Check(state)) { PyErr_SetString(PyExc_TypeError, @@ -353,16 +354,16 @@ } for (i=0; istate[i] = (unsigned long)element; + self->state[i] = element & 0xffffffffUL; /* Make sure we get sane state */ } - element = PyInt_AsLong(PyTuple_GET_ITEM(state, i)); - if (element == -1 && PyErr_Occurred()) + index = PyLong_AsLong(PyTuple_GET_ITEM(state, i)); + if (index == -1 && PyErr_Occurred()) return NULL; - self->index = (int)element; + self->index = (int)index; Py_INCREF(Py_None); return Py_None;