In C#, threads have an Abort
method that causes a ThreadAbortException
to be raised in them wherever they might be running. Python does not have this feature, and so it has been implemented. However, this implementation does not cause the exception to be automatically re-raised once at the end of all the exception handling.
Some experiments were tried with sys.settrace
and also ThreadAbortException.__del__
without success. These seem to be on the right track to implementing an exception that can automatically raise itself again. Unfortunately, a clean implementation that might also support a future ResetAbort
method for threads is a bit difficult for me to figure out.
Here is the implementation that has been written so far:
#! /usr/bin/env python3
import ctypes
import threading
PyThreadState_SetAsyncExc = ctypes.pythonapi.PyThreadState_SetAsyncExc
PyThreadState_SetAsyncExc.argtypes = ctypes.c_ulong, ctypes.py_object
PyThreadState_SetAsyncExc.restype = ctypes.c_int
def set_async_exc(thread_id, exception):
if not isinstance(thread_id, int):
raise TypeError('thread_id should be of type int')
if not issubclass(exception, BaseException):
raise TypeError('exception should be subclass of BaseException')
return PyThreadState_SetAsyncExc(thread_id, exception)
class ThreadAbortException(SystemExit):
pass
class CThread(threading.Thread):
def abort(self):
set_async_exc(self.ident, ThreadAbortException)
My expectation is an instance of the ThreadAbortException
should be able to automatically raise itself again sometime after it has been caught and handled. It would probably need to be raised either after the context in which it was handled is returning to a caller or when it is collected by the garbage collector. Does anyone have some idea how to accomplish this?