[Python-Dev] Simple coroutines?
Phillip J. Eby
pje at telecommunity.com
Wed Aug 25 18:13:46 CEST 2004
At 02:51 PM 8/25/04 +1200, Greg Ewing wrote:
>"Phillip J. Eby" <pje at telecommunity.com>:
> > If you could throw a special kind of exception (or even a regular
> > exception), and call traceback.resume() to pick up execution at the
> > point where it was thrown, whether thrown by a generator or a
> > regular function.
>Actually, it probably wouldn't be too hard to make exceptions
>resumable -- provided all the frames in between are Python. If the
>exception gets thrown through any C calls, though, resumption becomes
>impossible. Some other structure is needed to hold the state of a
>resumable C call.
Unfortunately, as was discussed on the previous Stackless thread, nearly
*all* Python bytecodes pass through C on their way to other Python code.
The trick is to be able to figure out whether the return value of a given
frame is being put onto the value stack of its parent frame. In principle,
you could tell this from the operation being performed at the current
opcode pointer in the parent frame, and the prior contents of the value
stack. In practice, the eval loop sometimes messes with the value stack
prior to the call (e.g. to optimize method calls), and in the case of e.g
try/finally and try/except, it's going to execute other stuff in the frame
before the exception is passed up to the next frame.
So, to make it work,the interpreter loop would need to be particular about
putting the stack back to the way it was before the current instruction
began, when an exception occurs. Also, it would need to *not* invoke
except/finally clauses for one of these special exceptions, or else have a
way of restoring the frame to its pre-exception state, which seems
arbitrarily complex. I guess it would have to treat the resumable
exception as if a YIELD operation took place.
I'm going to have to think about this one some more, but it seems to me
that it would be much easier to add bidirectional communication to
generators to create a coroutine type, than to try to implement resumable
More information about the Python-Dev