简体   繁体   English

Boost.Python自定义异常类

[英]Boost.Python custom exception class

I'm implementing a Python extension module using Boost.Python. 我正在使用Boost.Python实现一个Python扩展模块。 The module should define its own custom exception classes that inherit Exception . 该模块应定义自己的继承Exception的自定义异常类。 How do I do that? 我怎么做?

The following function creates a new Python exception class and adds it to the current scope. 以下函数创建一个新的Python异常类,并将其添加到当前范围。 If it is called in a module initialization function, then it is added to the module. 如果在模块初始化函数中调用它,则将其添加到模块中。

The first argument is the name of the new exception class. 第一个参数是新异常类的名称。 The second argument is the type object for the base class of the new exception class; 第二个参数是新异常类的基类的类型对象; it defaults to the type object for Exception . 它默认为Exception的类型对象。 The return value is the type object for the new exception class. 返回值是新异常类的类型对象。

PyObject* createExceptionClass(const char* name, PyObject* baseTypeObj = PyExc_Exception)
{
    using std::string;
    namespace bp = boost::python;

    string scopeName = bp::extract<string>(bp::scope().attr("__name__"));
    string qualifiedName0 = scopeName + "." + name;
    char* qualifiedName1 = const_cast<char*>(qualifiedName0.c_str());

    PyObject* typeObj = PyErr_NewException(qualifiedName1, baseTypeObj, 0);
    if(!typeObj) bp::throw_error_already_set();
    bp::scope().attr(name) = bp::handle<>(bp::borrowed(typeObj));
    return typeObj;
}

Use the function as follows: 使用如下功能:

Call the function in the module initialization function and store the return value in a global variable: 在模块初始化函数中调用函数并将返回值存储在全局变量中:

PyObject* myExceptionTypeObj = 0;

BOOST_PYTHON_MODULE(MyModule)
{
    ...
    myExceptionTypeObj = createExceptionClass("MyException");
    ...
}

Raise exception of type MyModule.MyException : MyModule.MyException类型的异常:

PyErr_SetString(myExceptionTypeObj, "Oh my!")

@Kenny: @Kenny:

If you refer to 如果你参考

PyErr_SetString(myExceptionTypeObj, "Oh my!")

I wouldn't regard this as "copying the string to a global object". 我不认为这是“将字符串复制到全局对象”。 Rather, it sets Python's internal error indicator so that the interpreter will raise an instance of myExceptionTypeObj at its next error indicator check. 相反,它设置Python的内部错误指示符,以便解释器在下一个错误指示符检查时引发myExceptionTypeObj的实例。

Python's exception handling works with a (per Python thread) global error indicator and this is the usual way to raise an exception through the C API afaict. Python的异常处理适用于(每个Python线程)全局错误指示器,这是通过C API提出异常的常用方法。

My take on it is you're safe if your holding the GIL at this moment and will properly cause an exception in the Python thread your C code was entered from. 我对此的看法是,如果您此时持有GIL并且在您输入C代码的Python线程中正确导致异常,那么您就是安全的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM