[Python-Dev] PyThreadState_SetAsyncExc bug? (original) (raw)
tomer filiba tomerfiliba at gmail.com
Fri Aug 11 11:27:32 CEST 2006
- Previous message: [Python-Dev] PyThreadState_SetAsyncExc bug?
- Next message: [Python-Dev] PyThreadState_SetAsyncExc bug?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
opened a new bug: http://sourceforge.net/tracker/index.php?func=detail&aid=1538556&group_id=5470&atid=105470
On 8/11/06, tomer filiba <tomerfiliba at gmail.com> wrote:
while working on a library for raising exceptions in the context of another thread, i've come across a bug in PyThreadStateSetAsyncExc. if i raise an instance, sys.excinfo() confuses the exception value for the exception type, and the exception value is set None. if i raise the type itself, the interpreter creates an instance internally, but then i can't pass arguments to the exception.
code: ===================================== import threading import ctypes
def asyncraise(tid, excobj): res = ctypes.pythonapi.PyThreadStateSetAsyncExc(tid, ctypes.pyobject(excobj)) if res == 0: raise ValueError("nonexistent thread id") elif res > 1: # """if it returns a number greater than one, you're in trouble, # and you should call it again with exc=NULL to revert the effect""" ctypes.pythonapi.PyThreadStateSetAsyncExc(tid, None) raise SystemError("PyThreadStateSetAsyncExc failed") class Thread(threading.Thread): def raiseexc(self, excobj): assert self.isAlive(), "thread must be started" for tid, tobj in threading.active.items(): if tobj is self: asyncraise(tid, excobj) break # the thread was alive when we entered the loop, but was not found # in the dict, hence it must have been already terminated. should we raise # an exception here? silently ignore? def terminate(self): self.raiseexc(SystemExit()) if name == "main": import time import sys iamactive = False def f(): global iamactive iamactive = True try: try: while True: time.sleep(0.01) except IOError, ex: print "IOError handler" except TypeError, ex: print "TypeError handler" print "ex=", repr(ex) typ, val, tb = sys.excinfo() print "typ=", repr(typ) print "val=", repr(val) print "tb=", tb finally: iamactive = False t1 = Thread(target = f) t1.start() time.sleep(1) t1.raiseexc(TypeError("blah blah")) while iamactive: time.sleep(0.01) print "!! thread terminated" output: ===================================== TypeError handler ex= None typ= <exceptions.TypeError instance at 0x00C15D28> # should be the type val= None # should be the instance tb= <traceback object at 0x00C159E0> !! thread terminated if i change: t1.raiseexc(TypeError("blah blah")) to: t1.raiseexc(TypeError) i get: ===================================== TypeError handler ex= <exceptions.TypeError instance at 0x00C159B8> typ= <class exceptions.TypeError at 0x00B945A0> val= <exceptions.TypeError instance at 0x00C159B8> tb= <traceback object at 0x00C15D00> !! thread terminated but then of course i can't pass arguments to the exception
-tomer
- Previous message: [Python-Dev] PyThreadState_SetAsyncExc bug?
- Next message: [Python-Dev] PyThreadState_SetAsyncExc bug?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]