MCPcopy Create free account
hub / github.com/METR/vivaria / InterruptibleThread

Class InterruptibleThread

pyhooks/pyhooks/python_server.py:126–165  ·  view source on GitHub ↗

A thread that can be interrupted with t.raiseException() Based on https://stackoverflow.com/a/325528

Source from the content-addressed store, hash-verified

124
125
126class InterruptibleThread(threading.Thread):
127 """
128 A thread that can be interrupted with t.raiseException()
129 Based on https://stackoverflow.com/a/325528
130 """
131
132 def run(self):
133 """
134 Catch uncaught exceptions and save them to t.exc.
135 Necessary to remove unwanted "Exception ignored in thread started by..." and "Exception ignored in sys.unraisablehook..."
136 https://stackoverflow.com/a/31614591
137 """
138 self.exc = None
139 try:
140 self.ret = self._target(*self._args, **self._kwargs) # type: ignore
141 except Exception as e:
142 self.exc = e
143
144 def raiseException(self, ExceptionClass):
145 """
146 Interrupt thread with an exception.
147 Exception happens after the current system call finishes executing.
148 (So eg time.sleep() is not interrupted.)
149 If exception isn't firing then you can try calling this in a loop.
150 """
151 if not self.is_alive():
152 return # do nothing
153 thread_id = self.ident
154 if thread_id is None:
155 raise Exception("couldn't get thread identifier")
156 res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
157 ctypes.c_long(thread_id), ctypes.py_object(ExceptionClass)
158 )
159 if res == 0:
160 raise ValueError("invalid thread id")
161 elif res != 1:
162 # "if it returns a number greater than one, you're in trouble,
163 # and you should call it again with exc=NULL to revert the effect"
164 ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(thread_id), None)
165 raise SystemError("PyThreadState_SetAsyncExc failed")
166
167
168worker_counter_box = [0] # just for logging

Callers 1

python_exec_syncFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected