Я пишу модуль расширения Python с потоками и проститутками.Мне нужно выбросить исключение из одного из моих потоков в основной поток Python.Для этого я использую int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
.В документации sayd:
exc
- это объект исключения, который нужно вызвать
Нет ничего проще.Но когда я вызываю PyThreadState_SetAsyncExc
с Exception
(на самом деле PyExc_Exception
) экземпляром как exc
, я получаю
SystemError: exception Exception('Error text') not a BaseException subclass
Я могу прочитать:), поэтому я попытался поставить не экземпляр класса (как я полагаю, как указано в документации), а объект класса напрямую как exc
, и это неправильно.Но в результате я не могу передать ему аргументы.
Этот код вызывает системную ошибку в основном потоке:
PyGILState_STATE gstate = PyGILState_Ensure();
PyThreadState_SetAsyncExc(self->main_thread_id, PyObject_CallObject(PyExc_Exception, Py_BuildValue("(s)", "Error text")));
PyGILState_Release(gstate);
Этот код вызывает ожидаемое Exception
в основном потоке:
PyGILState_STATE gstate = PyGILState_Ensure();
PyThreadState_SetAsyncExc(self->main_thread_id, PyExc_Exception);
PyGILState_Release(gstate);
Полный текст ошибки, IDLE показывает:
Traceback (most recent call last):
** IDLE Internal Exception:
File "C:\Python37-32\lib\idlelib\run.py", line 137, in main
request = rpc.request_queue.get(block=True, timeout=0.05)
File "C:\Python37-32\lib\queue.py", line 179, in get
self.not_empty.wait(remaining)
File "C:\Python37-32\lib\threading.py", line 300, in wait
gotit = waiter.acquire(True, timeout)
SystemError: exception Exception('Error text') not a BaseException subclass
Итак, я ожидал, PyThreadState_SetAsyncExc
поддерживает объекты экземпляра исключения, но похоже, что он поддерживает только объекты класса / типа.Я прав?Или, может быть, я делаю это неправильно?