Skip to content

Instantly share code, notes, and snippets.

@nazavode
Forked from liuw/ctype_async_raise.py
Last active August 9, 2023 15:48
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nazavode/84d1371e023bccd2301e to your computer and use it in GitHub Desktop.
Save nazavode/84d1371e023bccd2301e to your computer and use it in GitHub Desktop.
Nasty hack to raise exception for other threads
from __future__ import print_function
import ctypes
import threading
import time
def async_raise(thread_obj, exception):
""" Raises an exception inside an arbitrary active :class:`~threading.Thread`.
Parameters
----------
thread_obj : :class:`~threading.Thread`
The target thread.
exception : ``Exception``
The exception class to be raised.
Raises
------
ValueError
The specified :class:`~threading.Thread` is not active.
SystemError
The raise operation failed, the interpreter has been left in an inconsistent state.
"""
target_tid = thread_obj.ident
if target_tid not in {thread.ident for thread in threading.enumerate()}:
raise ValueError('Invalid thread object, cannot find thread identity among currently active threads.')
affected_count = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(target_tid), ctypes.py_object(exception))
if affected_count == 0:
raise ValueError('Invalid thread identity, no thread has been affected.')
elif affected_count > 1:
ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(target_tid), ctypes.c_long(0))
raise SystemError("PyThreadState_SetAsyncExc failed, broke the interpreter state.")
if __name__ == '__main__':
def f():
try:
while True:
time.sleep(1)
finally:
print("Exited")
t = threading.Thread(target=f)
t.start()
print("Thread started")
print(t.isAlive())
time.sleep(5)
async_raise(t, SystemExit)
t.join()
print(t.isAlive())
@nazavode
Copy link
Author

nazavode commented Dec 1, 2015

Now works pretty seamlessly on Python 3.4. This remains one of the dirtiest hacks ever seen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment