Fixing the problem stated in issue 2702 with the patch submitted

in the issue 3165. Now cPickle does not fails with uncontrolled
behaviour when pickling into a very deep nested structure.
This commit is contained in:
Facundo Batista 2008-06-22 23:19:14 +00:00
parent 2694eb0219
commit 9da18b3133
2 changed files with 20 additions and 2 deletions

View File

@ -1,4 +1,4 @@
import cPickle import cPickle, unittest
from cStringIO import StringIO from cStringIO import StringIO
from test.pickletester import AbstractPickleTests, AbstractPickleModuleTests from test.pickletester import AbstractPickleTests, AbstractPickleModuleTests
from test import test_support from test import test_support
@ -90,12 +90,28 @@ class cPickleFastPicklerTests(AbstractPickleTests):
b = self.loads(self.dumps(a)) b = self.loads(self.dumps(a))
self.assertEqual(a, b) self.assertEqual(a, b)
class Node(object):
pass
class cPickleDeepRecursive(unittest.TestCase):
'''Issue 2702. This should raise a RecursionLimit but in some
platforms (FreeBSD, win32) sometimes raises KeyError instead,
or just silently terminates the interpreter (=crashes).
'''
def test_deep_recursive(self):
nodes = [Node() for i in range(500)]
for n in nodes:
n.connections = list(nodes)
n.connections.remove(n)
self.assertRaises(RuntimeError, cPickle.dumps, n)
def test_main(): def test_main():
test_support.run_unittest( test_support.run_unittest(
cPickleTests, cPickleTests,
cPicklePicklerTests, cPicklePicklerTests,
cPickleListPicklerTests, cPickleListPicklerTests,
cPickleFastPicklerTests cPickleFastPicklerTests,
cPickleDeepRecursive,
) )
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -1519,6 +1519,7 @@ batch_list(Picklerobject *self, PyObject *iter)
PyObject *obj; PyObject *obj;
PyObject *slice[BATCHSIZE]; PyObject *slice[BATCHSIZE];
int i, n; int i, n;
self->nesting++;
static char append = APPEND; static char append = APPEND;
static char appends = APPENDS; static char appends = APPENDS;
@ -1658,6 +1659,7 @@ batch_dict(Picklerobject *self, PyObject *iter)
PyObject *p; PyObject *p;
PyObject *slice[BATCHSIZE]; PyObject *slice[BATCHSIZE];
int i, n; int i, n;
self->nesting++;
static char setitem = SETITEM; static char setitem = SETITEM;
static char setitems = SETITEMS; static char setitems = SETITEMS;