diff options
author | Facundo Batista <facundobatista@gmail.com> | 2008-06-30 01:10:55 (GMT) |
---|---|---|
committer | Facundo Batista <facundobatista@gmail.com> | 2008-06-30 01:10:55 (GMT) |
commit | 763d309bba339c8609484c1cb03942ba684aa40c (patch) | |
tree | 310e4687a6aaa4fd837345f36cc91712536a2fdc | |
parent | 1e022689b71118d09815fb36173dccbb3bb33447 (diff) | |
download | cpython-763d309bba339c8609484c1cb03942ba684aa40c.zip cpython-763d309bba339c8609484c1cb03942ba684aa40c.tar.gz cpython-763d309bba339c8609484c1cb03942ba684aa40c.tar.bz2 |
Fix #2702, with a correct accounting of recursion.
-rw-r--r-- | Lib/test/test_cpickle.py | 26 | ||||
-rw-r--r-- | Modules/cPickle.c | 24 |
2 files changed, 25 insertions, 25 deletions
diff --git a/Lib/test/test_cpickle.py b/Lib/test/test_cpickle.py index 7d3fc97..0b02b62 100644 --- a/Lib/test/test_cpickle.py +++ b/Lib/test/test_cpickle.py @@ -94,23 +94,19 @@ class Node(object): pass class cPickleDeepRecursive(unittest.TestCase): -# I commented out, because the patch that fixes this was reverted, as -# it broke the next test case. Check the issues for full history. -# def test_issue2702(self): -# '''This should raise a RecursionLimit but in some -# platforms (FreeBSD, win32) sometimes raises KeyError instead, -# or just silently terminates the interpreter (=crashes). -# ''' -# 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_issue2702(self): + # This should raise a RecursionLimit but in some + # platforms (FreeBSD, win32) sometimes raises KeyError instead, + # or just silently terminates the interpreter (=crashes). + 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_issue3179(self): - '''Safe test, because of I broken this case when fixing the - behaviour for the previous test. - ''' + # Safe test, because I broke this case when fixing the + # behaviour for the previous test. res=[] for x in range(1,2000): res.append(dict(doc=x, similar=[])) diff --git a/Modules/cPickle.c b/Modules/cPickle.c index afa75fd..7f4ad7e 100644 --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -339,7 +339,6 @@ typedef struct Picklerobject { int bin; int fast; /* Fast mode doesn't save in memo, don't use if circ ref */ - int nesting; int (*write_func)(struct Picklerobject *, const char *, Py_ssize_t); char *write_buf; int buf_size; @@ -1630,7 +1629,12 @@ save_list(Picklerobject *self, PyObject *args) iter = PyObject_GetIter(args); if (iter == NULL) goto finally; - res = batch_list(self, iter); + + if (Py_EnterRecursiveCall(" while pickling an object") == 0) + { + res = batch_list(self, iter); + Py_LeaveRecursiveCall(); + } Py_DECREF(iter); finally: @@ -1786,7 +1790,11 @@ save_dict(Picklerobject *self, PyObject *args) iter = PyObject_CallMethod(args, "iteritems", "()"); if (iter == NULL) goto finally; - res = batch_dict(self, iter); + if (Py_EnterRecursiveCall(" while pickling an object") == 0) + { + res = batch_dict(self, iter); + Py_LeaveRecursiveCall(); + } Py_DECREF(iter); finally: @@ -2306,11 +2314,8 @@ save(Picklerobject *self, PyObject *args, int pers_save) int res = -1; int tmp, size; - if (self->nesting++ > Py_GetRecursionLimit()){ - PyErr_SetString(PyExc_RuntimeError, - "maximum recursion depth exceeded"); - goto finally; - } + if (Py_EnterRecursiveCall(" while pickling an object")) + return -1; if (!pers_save && self->pers_func) { if ((tmp = save_pers(self, args, self->pers_func)) != 0) { @@ -2559,7 +2564,7 @@ save(Picklerobject *self, PyObject *args, int pers_save) res = save_reduce(self, t, args); finally: - self->nesting--; + Py_LeaveRecursiveCall(); Py_XDECREF(py_ob_id); Py_XDECREF(__reduce__); Py_XDECREF(t); @@ -2801,7 +2806,6 @@ newPicklerobject(PyObject *file, int proto) self->inst_pers_func = NULL; self->write_buf = NULL; self->fast = 0; - self->nesting = 0; self->fast_container = 0; self->fast_memo = NULL; self->buf_size = 0; |