From: <zy...@us...> - 2008-08-10 22:57:10
|
Revision: 5138 http://jython.svn.sourceforge.net/jython/?rev=5138&view=rev Author: zyasoft Date: 2008-08-10 22:57:07 +0000 (Sun, 10 Aug 2008) Log Message: ----------- Properly closes a generator upon close/throw including throwing StopIteration upon a send to a closed generator. Modified Paths: -------------- branches/asm/src/org/python/core/PyGenerator.java Modified: branches/asm/src/org/python/core/PyGenerator.java =================================================================== --- branches/asm/src/org/python/core/PyGenerator.java 2008-08-10 21:30:15 UTC (rev 5137) +++ branches/asm/src/org/python/core/PyGenerator.java 2008-08-10 22:57:07 UTC (rev 5138) @@ -14,6 +14,7 @@ this.gi_running = false; // Create an exception instance while we have a frame to create it from. // When the GC runs it doesn't have any associated thread state. + // this is necessary for finalize calling close on the generator this.generatorExit = Py.makeException(Py.GeneratorExit); } @@ -34,6 +35,9 @@ } public PyObject send(PyObject value) { + if (gi_frame == null) { + throw Py.StopIteration(""); + } if (gi_frame.f_lasti == 0 && value != Py.None) { throw Py.TypeError("can't send non-None value to a just-started generator"); } @@ -42,6 +46,8 @@ } private PyObject raiseException(PyException ex) { + if (gi_frame == null) + return null; gi_frame.setGeneratorInput(ex); return next(); } @@ -71,14 +77,11 @@ } protected void finalize() throws Throwable { - //if (gi_frame.f_lasti == -1) // Generator already closed. - // return; // this is pure optimization + if (gi_frame == null || gi_frame.f_lasti == -1) + return; try { - close(); // close doesn't work without newcompiler, so ignore the exception + close(); } catch (Throwable e) { - // e.printStackTrace(); - // Py.println(Py.getSystemState().stderr, new PyString("Exception " - // + e + " in " + this + " ignored.")); } finally { super.finalize(); } @@ -87,27 +90,33 @@ public PyObject __iternext__() { if (gi_running) throw Py.ValueError("generator already executing"); - if (gi_frame.f_lasti == -1) + if (gi_frame == null) { return null; + } + + if (gi_frame.f_lasti == -1) { + gi_frame = null; + return null; + } gi_running = true; PyObject result = null; try { result = gi_frame.f_code.call(gi_frame, closure); } catch(PyException e) { - if(!e.type.equals(Py.StopIteration)) { + if (!(e.type == Py.StopIteration || e.type == Py.GeneratorExit)) { + gi_frame = null; throw e; } else { stopException = e; + gi_frame = null; return null; } } finally { gi_running = false; } -// System.out.println("lasti:" + gi_frame.f_lasti); -//if (result == Py.None) -// new Exception().printStackTrace(); - if (result == Py.None && gi_frame.f_lasti == -1) + if (result == Py.None && gi_frame.f_lasti == -1) { return null; + } return result; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |