[Python-checkins] r45409 - in python/trunk: Lib/test/test_generators.py Objects/frameobject.c Objects/genobject.c (original) (raw)

phillip.eby python-checkins at python.org
Sat Apr 15 03:02:21 CEST 2006


Author: phillip.eby Date: Sat Apr 15 03:02:17 2006 New Revision: 45409

Modified: python/trunk/Lib/test/test_generators.py python/trunk/Objects/frameobject.c python/trunk/Objects/genobject.c Log: Fix SF#1470508: crash in generator cycle finalization. There were two problems: first, PyGen_NeedsFinalizing() had an off-by-one bug that prevented it from ever saying a generator didn't need finalizing, and second, frame objects cleared themselves in a way that caused their owning generator to think they were still executable, causing a double deallocation of objects on the value stack if there was still a loop on the block stack. This revision also removes some unnecessary close() operations from test_generators that are now appropriately handled by the cycle collector.

Modified: python/trunk/Lib/test/test_generators.py

--- python/trunk/Lib/test/test_generators.py (original) +++ python/trunk/Lib/test/test_generators.py Sat Apr 15 03:02:17 2006 @@ -421,7 +421,6 @@ ... self.name = name ... self.parent = None ... self.generator = self.generate() -... self.close = self.generator.close ... ... def generate(self): ... while not self.parent: @@ -484,8 +483,6 @@ merged A into G A->G B->G C->G D->G E->G F->G G->G H->G I->G J->G K->G L->G M->G ->>> for s in sets: s.close() # break cycles

""" # Emacs turd ' @@ -593,7 +590,6 @@ ... def init(self, g): ... self.sofar = [] ... self.fetch = g.next -... self.close = g.close ... ... def getitem(self, i): ... sofar, fetch = self.sofar, self.fetch @@ -624,8 +620,6 @@ [200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, 384] [400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675] ->>> m235.close()

Ye olde Fibonacci generator, LazyList style.

def fibgen(a, b): @@ -648,7 +642,6 @@ fib = LazyList(fibgen(1, 2)) firstn(iter(fib), 17) [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584] ->>> fib.close()

Running after your tail with itertools.tee (new in version 2.4)

Modified: python/trunk/Objects/frameobject.c

--- python/trunk/Objects/frameobject.c (original) +++ python/trunk/Objects/frameobject.c Sat Apr 15 03:02:17 2006 @@ -454,9 +454,15 @@ static void frame_clear(PyFrameObject *f) { - PyObject **fastlocals, **p; + PyObject **fastlocals, **p, **oldtop; int i, slots;

@@ -473,17 +479,13 @@ slots = f->f_nlocals + f->f_ncells + f->f_nfreevars; fastlocals = f->f_localsplus; for (i = slots; --i >= 0; ++fastlocals) { - if (*fastlocals != NULL) { - Py_XDECREF(*fastlocals); - *fastlocals = NULL; - } + Py_CLEAR(*fastlocals); }

 /* stack */

Modified: python/trunk/Objects/genobject.c

--- python/trunk/Objects/genobject.c (original) +++ python/trunk/Objects/genobject.c Sat Apr 15 03:02:17 2006 @@ -35,7 +35,7 @@ } _PyObject_GC_UNTRACK(self); - Py_XDECREF(gen->gi_frame); + Py_CLEAR(gen->gi_frame); PyObject_GC_Del(gen); } @@ -130,8 +130,8 @@ "generator ignored GeneratorExit"); return NULL; } - if ( PyErr_ExceptionMatches(PyExc_StopIteration) - || PyErr_ExceptionMatches(PyExc_GeneratorExit) ) + if ( PyErr_ExceptionMatches(PyExc_StopIteration) + || PyErr_ExceptionMatches(PyExc_GeneratorExit) ) { PyErr_Clear(); /* ignore these errors */ Py_INCREF(Py_None); @@ -208,7 +208,7 @@ return next yielded value or raise StopIteration."); static PyObject * -gen_throw(PyGenObject *gen, PyObject *args) +gen_throw(PyGenObject *gen, PyObject *args) { PyObject *typ; PyObject tb = NULL; @@ -328,7 +328,7 @@ 0, / tp_getset / 0, / tp_base / 0, / tp_dict */

@@ -366,15 +366,16 @@ int i; PyFrameObject *f = gen->gi_frame;



More information about the Python-checkins mailing list