'PyThreadState_SetAsyncExc' вызывает 'SystemError: исключение Exception (), а не подкласс BaseException' - PullRequest
2 голосов
/ 28 марта 2019

Я пишу модуль расширения 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 поддерживает объекты экземпляра исключения, но похоже, что он поддерживает только объекты класса / типа.Я прав?Или, может быть, я делаю это неправильно?

...