At 01:16 PM 8/25/04 -0400, Clark C. Evans wrote:
On Wed, Aug 25, 2004 at 12:13:46PM -0400, Phillip J. Eby wrote: | At 02:51 PM 8/25/04 +1200, Greg Ewing wrote: | >> 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.
However, the C code in the distribution could be scrubbed to make sure that it works with the mechanism. And the C API could be detailed so that this case is managable; else, it is an "uncaught" exception.
Quick question: does Stackless' "greenlet" extension module do what you need? I just built it and played around with it a bit. One of the demos is a pseudo-generator implementation using a 'Yield' function that uses greenlet task switching to simulate the behavior of a normal generator function. It looks to me that your "yield Cooperate" scenarios could perhaps be met by simply switching to a reactor/mainloop greenlet, when it's necessary to wait for an event, and by having your event callback switch back to the task's greenlet, returning a result if needed. Interestingly, this greenlet thing looks like it would be perfect for peak.events, allowing me to get rid of all the generators and yield/resume stuff. (In fairness, Bob Ippolito told me that before I ever implemented peak.events, but at the time greenlets didn't exist as an extension module that could be built outside of Stackless.)