c++ - Clase de excepción personalizada Boost.Python
exception boost-python (2)
Estoy implementando un módulo de extensión de Python usando Boost.Python. El módulo debe definir sus propias clases de excepciones personalizadas que heredan Exception
. ¿Cómo puedo hacer eso?
@ Kenny:
Si te refieres a
PyErr_SetString(myExceptionTypeObj, "Oh my!")
No consideraría esto como "copiar la cadena a un objeto global". Por el contrario, establece el indicador de error interno de Python para que el intérprete genere una instancia de myExceptionTypeObj en su próxima comprobación de indicador de error.
El manejo de excepciones de Python funciona con un indicador de error global (por hilo de Python) y esta es la manera habitual de generar una excepción a través de la API de C afaict.
Mi opinión es si estás seguro si tienes el GIL en este momento y causarás una excepción en el subproceso de Python desde el que se ingresó tu código C.
La siguiente función crea una nueva clase de excepción de Python y la agrega al alcance actual. Si se llama en una función de inicialización del módulo, entonces se agrega al módulo.
El primer argumento es el nombre de la nueva clase de excepción. El segundo argumento es el tipo de objeto para la clase base de la nueva clase de excepción; se predetermina al objeto tipo para Exception
. El valor de retorno es el tipo de objeto para la nueva clase de excepción.
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 la función de la siguiente manera:
Llame a la función en la función de inicialización del módulo y almacene el valor de retorno en una variable global:
PyObject* myExceptionTypeObj = 0;
BOOST_PYTHON_MODULE(MyModule)
{
...
myExceptionTypeObj = createExceptionClass("MyException");
...
}
Elevar la excepción de tipo MyModule.MyException
:
PyErr_SetString(myExceptionTypeObj, "Oh my!")