python - 'PyThreadState_SetAsyncExc' 导致 'SystemError: exception Exception() not a BaseException subclass'

标签 python multithreading exception python-c-api

我正在用线程和钩子(Hook)编写 Python 扩展模块。我需要从我的一个线程向 Python 主线程抛出异常。为此我使用 int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) .在文档中说:

exc is the exception object to be raised



没有什么比这更容易的了。但是当我调用 PyThreadState_SetAsyncExcException (实际上是 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支持异常实例对象,但看起来它只支持类/类型对象。
我对么?或者也许我做错了?

最佳答案

是的,你是对的。您需要指定一个异常(exception) 类型 ,而不是 实例 .文档可能对此更清楚。

如果要提供带有异常的自定义错误消息,可以使用 PyErr_NewException创建自己的异常类型的函数:

PyGILState_STATE gstate = PyGILState_Ensure();
PyObject* exc = PyErr_NewException("mymodule.MyError: error message", NULL, NULL);
PyThreadState_SetAsyncExc(self->main_thread_id, exc);
Py_DECREF(exc);
PyGILState_Release(gstate);

关于python - 'PyThreadState_SetAsyncExc' 导致 'SystemError: exception Exception() not a BaseException subclass',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55397010/

相关文章:

python - 使用 Python 抓取网站时设置代理

python - 如何从这里获取 span=(2494, 2516) 的第一个数字?

java - 返回响应实体中断流程

python - 计算在 Selenium Python 中打开的选项卡数量

multithreading - Delphi 2007 中的 AsyncCall

java - 同步是否锁定结果集对象?

java - Spring Boot 将事务(和数据库连接)传播到 @Async 方法

javascript - 收到 JQUERY "syntax error, unrecognized expression"

exception - mips异常处理beq无法正常工作

python - Pandas 忽略缺失的日期来查找百分位数