2012-03-08 13 views
11

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?Boost.Python clase de excepción personalizada

+1

Haga que sus errores hereden de 'Exception'; 'StandardError' es usado por errores generados por herramientas de la biblioteca estándar de python. – Daenyth

+0

@Daenyth: tienes razón. He revisado la pregunta. – user763305

Respuesta

12

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; 
} 

utilizar la función de la siguiente manera:

Llame a la función en la función de inicialización del módulo y almacenar el valor devuelto en una variable global: excepción

PyObject* myExceptionTypeObj = 0; 

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

Raise del tipo MyModule.MyException:

PyErr_SetString(myExceptionTypeObj, "Oh my!") 
+4

Diga 'MyException' realmente se asigna a un tipo de C++. ¿Cómo expondría a sus miembros? – Barry

-1

@Kenny:

Si se refiere a

PyErr_SetString(myExceptionTypeObj, "Oh my!") 

yo no considerar esto como "la copia de la cadena en 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 forma habitual de generar una excepción a través de la API C.

Mi opinión es que 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.

Cuestiones relacionadas