mirror of
https://github.com/python/cpython.git
synced 2026-01-06 15:32:22 +00:00
Issue #1727780: Support loading pickles of random.Random objects created
on 32-bit systems on 64-bit systems, and vice versa. As a consequence of the change, Random pickles created by Python 2.6 cannot be loaded in Python 2.5.
This commit is contained in:
parent
2ec7415db5
commit
6b449f4f2b
10 changed files with 45 additions and 10 deletions
|
|
@ -80,6 +80,9 @@ Bookkeeping functions:
|
|||
|
||||
.. versionadded:: 2.1
|
||||
|
||||
.. versionchanged:: 2.6
|
||||
State values produced in Python 2.6 cannot be loaded into earlier versions.
|
||||
|
||||
|
||||
.. function:: setstate(state)
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ class Random(_random.Random):
|
|||
|
||||
"""
|
||||
|
||||
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 getstate(self):
|
|||
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" %
|
||||
|
|
|
|||
BIN
Lib/test/randv2_32.pck
Normal file
BIN
Lib/test/randv2_32.pck
Normal file
Binary file not shown.
BIN
Lib/test/randv2_64.pck
Normal file
BIN
Lib/test/randv2_64.pck
Normal file
Binary file not shown.
BIN
Lib/test/randv3.pck
Normal file
BIN
Lib/test/randv3.pck
Normal file
Binary file not shown.
|
|
@ -140,6 +140,19 @@ def test_pickling(self):
|
|||
restoredseq = [newgen.random() for i in xrange(10)]
|
||||
self.assertEqual(origseq, restoredseq)
|
||||
|
||||
def test_bug_1727780(self):
|
||||
# verify that version-2-pickles can be loaded
|
||||
# fine, whether they are created on 32-bit or 64-bit
|
||||
# platforms, and that version-3-pickles load fine.
|
||||
files = [("randv2_32.pck", 780),
|
||||
("randv2_64.pck", 866),
|
||||
("randv3.pck", 343)]
|
||||
for file, value in files:
|
||||
f = open(test_support.findfile(file),"rb")
|
||||
r = pickle.load(f)
|
||||
f.close()
|
||||
self.assertEqual(r.randrange(1000), value)
|
||||
|
||||
class WichmannHill_TestBasicOps(TestBasicOps):
|
||||
gen = random.WichmannHill()
|
||||
|
||||
|
|
|
|||
|
|
@ -395,6 +395,7 @@ Marc-Andre Lemburg
|
|||
Mark Levinson
|
||||
William Lewis
|
||||
Robert van Liere
|
||||
Shawn Ligocki
|
||||
Martin Ligr
|
||||
Christopher Lindblad
|
||||
Eric Lindvall
|
||||
|
|
|
|||
|
|
@ -308,6 +308,11 @@ Core and builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #1727780: Support loading pickles of random.Random objects created
|
||||
on 32-bit systems on 64-bit systems, and vice versa. As a consequence
|
||||
of the change, Random pickles created by Python 2.6 cannot be loaded
|
||||
in Python 2.5.
|
||||
|
||||
- Issue #1455: The distutils package now supports VS 2005 and VS 2008 for
|
||||
both the msvccompiler and cygwincompiler.
|
||||
|
||||
|
|
|
|||
|
|
@ -319,12 +319,12 @@ random_getstate(RandomObject *self)
|
|||
if (state == NULL)
|
||||
return NULL;
|
||||
for (i=0; i<N ; i++) {
|
||||
element = PyInt_FromLong((long)(self->state[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 @@ static PyObject *
|
|||
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 @@ random_setstate(RandomObject *self, PyObject *state)
|
|||
}
|
||||
|
||||
for (i=0; i<N ; i++) {
|
||||
element = PyInt_AsLong(PyTuple_GET_ITEM(state, i));
|
||||
element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i));
|
||||
if (element == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
self->state[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;
|
||||
|
|
|
|||
|
|
@ -933,6 +933,7 @@ def add_files(db):
|
|||
lib.add_file("empty.vbs")
|
||||
lib.glob("*.uue")
|
||||
lib.glob("*.pem")
|
||||
lib.glob("*.pck")
|
||||
lib.add_file("readme.txt", src="README")
|
||||
if dir=='decimaltestdata':
|
||||
lib.glob("*.decTest")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue