[Stackless] send_exception does not take an instance

Andrew Dalke dalke at dalkescientific.com
Tue Feb 20 08:26:50 CET 2007


I expected I could use send_exception to pass an Exception
instance.  That is not the case - the function requires an
exception class or a string.  (Note: string exceptions are
highly deprecated these days).  Here's the signature in
the docstring, explicitly saying that what I was is not allowed:

     channel.send_exception(exc, value)

The code I had hoped would work is



import stackless

request_ch = stackless.channel()
response_ch = stackless.channel()

def divider():
     while 1:
         x, y = request_ch.receive()
         try:
             response_ch.send( x/y )
         except Exception, err:
             response_ch.send_exception(err)

def divide(top, bottom):
     request_ch.send( (top, bottom) )
     return response_ch.receive()

def main(numerator, denominator):
     try:
	result = divide(numerator, denominator)
     except ZeroDivisionError:
	result = None
     print "%s/%s = %s" % (numerator, denominator, result)

stackless.tasklet(divider)()
stackless.tasklet(main)(8, 0)
stackless.run()


It appears there is no simple way to do this.  I
need to disassemble and reassemble the exception
like this (for the general case; there are shorter
ways to handle this specific case)


import stackless
import sys

request_ch = stackless.channel()
response_ch = stackless.channel()

class WrapperException(Exception):
     def __init__(self, info):
	self.info = info

def divider():
     while 1:
         x, y = request_ch.receive()
         try:
             response_ch.send( x/y )
         except Exception:
	    response_ch.send_exception(WrapperException, sys.exc_info())

def divide(top, bottom):
     request_ch.send( (top, bottom) )
     try:
	return response_ch.receive()
     except WrapperException, err:
	raise err.info[0], err.info[1], err.info[2]

def main(numerator, denominator):
     try:
	result = divide(numerator, denominator)
     except ZeroDivisionError:
	result = None
     print "%s/%s = %s" % (numerator, denominator, result)

stackless.tasklet(divider)()
stackless.tasklet(main)(8, 0)
stackless.run()



While I don't use it in this case, I pass sys.exc_info() around
so the full stack trace is available in the calling tasklet.
This replicates existing Stackless behavior for send_exception.


This is inelegant at best, though it works.  I think Stackless
should have a way to send an instance of Exception or derived
class as well.

Please let me know if there is a better solution.  If not,
consider this a feature request.

				Andrew
				dalke at dalkescientific.com




_______________________________________________
Stackless mailing list
Stackless at stackless.com
http://www.stackless.com/mailman/listinfo/stackless



More information about the Stackless mailing list