[c++-sig] How to raise a python exception in boost.python?
I have read the python C API manual for exception handling. It seems that if the function below is called, python interpreter will get a ValueError exception, PyObject* RaiseValueError(PyObject*) { PyErr_SetString(PyExc_ValueError, "for some reason..."); return 0; } just like the statement in python:
raise ValueError("for some reason...") Is that right??
Ok, but if I move this function into boost.python, the exception disappeared. object RaiseValueError(object) { PyErr_SetString(PyExc_ValueError, "for some reason..."); return object(); } If I throw a C++ exception, later on the boundary of boost.python, it will be translated into a python exception: (in boost file errors.cpp) BOOST_PYTHON_DECL bool handle_exception_impl(function0<void> f) { try { if (detail::exception_handler::chain) return detail::exception_handler::chain->handle(f); f(); return false; } catch(const boost::python::error_already_set&) { // The python error reporting has already been handled. } catch(const std::bad_alloc&) { PyErr_NoMemory(); } catch(const bad_numeric_cast& x) { PyErr_SetString(PyExc_OverflowError, x.what()); } catch(const std::out_of_range& x) { PyErr_SetString(PyExc_IndexError, x.what()); } catch(const std::exception& x) { PyErr_SetString(PyExc_RuntimeError, x.what()); } catch(...) { PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception"); } return true; } So, I'm really confused. Why does NOT my calling to PyErr_SetString work, while boost.python similar calling works? Does boost.python eats my error flags? Anyway, my goal is the raise a python exception (eg: ValueError) from boost.python based code. How to do that? (Do not tell me to write a custom exception translator and plug it into boost.python... -_-!! The only thing I need is just to raise a python exception directly.) Thank you. --- ShenLei
2007/6/6, 甜瓜 <littlesweetmelon@gmail.com>:
I have read the python C API manual for exception handling. It seems that if the function below is called, python interpreter will get a ValueError exception, PyObject* RaiseValueError(PyObject*) { PyErr_SetString(PyExc_ValueError, "for some reason..."); return 0; } just like the statement in python:
raise ValueError("for some reason...") Is that right??
Ok, but if I move this function into boost.python, the exception disappeared. object RaiseValueError(object) { PyErr_SetString(PyExc_ValueError, "for some reason..."); return object(); }
If I throw a C++ exception, later on the boundary of boost.python, it will be translated into a python exception: (in boost file errors.cpp)
BOOST_PYTHON_DECL bool handle_exception_impl(function0<void> f) { try { if (detail::exception_handler::chain) return detail::exception_handler::chain->handle(f); f(); return false; } catch(const boost::python::error_already_set&) { // The python error reporting has already been handled. } catch(const std::bad_alloc&) { PyErr_NoMemory(); } catch(const bad_numeric_cast& x) { PyErr_SetString(PyExc_OverflowError, x.what()); } catch(const std::out_of_range& x) { PyErr_SetString(PyExc_IndexError, x.what()); } catch(const std::exception& x) { PyErr_SetString(PyExc_RuntimeError, x.what()); } catch(...) { PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception"); } return true; }
So, I'm really confused. Why does NOT my calling to PyErr_SetString work, while boost.python similar calling works? Does boost.python eats my error flags?
Anyway, my goal is the raise a python exception (eg: ValueError) from boost.python based code. How to do that? (Do not tell me to write a custom exception translator and plug it into boost.python... -_-!! The only thing I need is just to raise a python exception directly.)
Thank you. --- ShenLei
Oh~~ I solved this problem by myself. I forgot to call throw_error_already_set() to tell boost.python that python error has occurred. Sorry for such newbie mistake. ^_^ --- ShenLei
participants (1)
-
甜瓜