It seems that exception handlers get tied to subroutines when they're created, not when they're actually used. For example:
## this works: try: f = make_function() f.die() # raise some error except: pass ## this does not work: f = make_function() try: f.die() # raise some error except: pass This is a problem in general, but especially for me because in python, a generator returns an object, and you call that object's next() over and over until you get a StopIteration. Unfortunately, I can't *trap* that StopIteration in a "try" block unless I create the generator inside that same block. Following is a detailed test case in imc that illustrates the problem. Sincerely, Michal J Wallace Sabren Enterprises, Inc. ------------------------------------- contact: [EMAIL PROTECTED] hosting: http://www.cornerhost.com/ my site: http://www.withoutane.com/ -------------------------------------- ## generator_try_bug.imc ## this exposes a bug in parrot exception handling ## a function returns a function and that function ## throws an error. The error is not caught. .sub __main__ new_pad 0 # count() returns a generator .local object count newsub count, .Closure, _count # here's where we'll store it .local object generator # if "try:" is around the CREATION of the generator, # everything works fine. but we don't want that, so # this is commented out. # # .local Sub handler # newsub handler, .Exception_Handler, catch0 # set_eh handler # call count and get the generator .local Sub retlabel0 newsub retlabel0, .Continuation, ret0 .pcc_begin non_prototyped .pcc_call count, retlabel0 ret0: .result generator .pcc_end ## HERE IS where we want the try block to start #### .local Sub handler newsub handler, .Exception_Handler, catch0 set_eh handler # now call the generator, which throws 'StopIteration' .local Sub retlabel1 newsub retlabel1, .Continuation, ret1 .pcc_begin non_prototyped .pcc_call generator, retlabel1 ret1: .result $P3 .pcc_end # end the "try" block (we never get here) clear_eh goto endtry0 catch0: print "caught it!" endtry0: end .end # here is count(), which returns the generator .pcc_sub _count non_prototyped .local object gen_fun .local object gen_obj newsub gen_fun, .Coroutine, _count_g .pcc_begin_return .return gen_fun .pcc_end_return .end # here is the generator itself # all it does is throw StopIteration .pcc_sub _count_g non_prototyped .local object ex0 .local object msg0 ex0 = new Exception msg0 = new PerlString msg0 = 'StopIteration' ex0['_message'] = msg0 throw ex0 .end ## end of test case ###############################