python - “PyThreadState_SetAsyncExc”导致“SystemError:异常 Exception()不是 BaseException 子类”
问题描述
我正在用线程和钩子编写 Python 扩展模块。我需要从我的一个线程向 Python 主线程抛出异常。为此我使用int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
. 在文档中说:
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
支持异常实例对象,但看起来它只支持类/类型对象。我对么?或者也许我做错了?
解决方案
是的,你是对的。您需要指定异常类型,而不是实例。文档可能对此更清楚。
如果要为异常提供自定义错误消息,可以使用该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);
推荐阅读
- bash - 如何以毫秒为单位设置创建日期和时间到文件?
- python - 正则表达式用多行 Python 匹配和替换字符串
- python - 如何克服 Javascript “onclick” 按钮以使用 Selenium 抓取网页
- unit-testing - 在“ npm test login.component.spect.ts”上,它说“无法从'login.component.ts'中找到模块'@app/store/user/user.actions'
- c# - 为什么`float`声明是这样`public struct Single`
- python - 将txt文件最后N行的数据提取到python中的数组中
- python - 如何在python中使用xlrd读取一个空的excel单元格
- node.js - 如何修复节点 js + redis + mongodb Web 应用程序中的竞争条件
- ios - RxSwift 订阅将在启动时起作用
- angular - 如何在任何事件上重新初始化 ag-grid?