Created
August 26, 2016 19:49
-
-
Save pavelschon/35e1e88b0f8aea38213a0cb9c8061306 to your computer and use it in GitHub Desktop.
Translate Python exception into C++ exception (Boost::Python)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @brief Generic Python-to-C++ exception translator | |
* Caller provides C++ exception class, callback(), list of Python exceptions, | |
* which should be be handled and optional parameters to callback | |
* | |
* @param callback object, usually python function, lambda function, functor, std::bind expression or std::function | |
* @param exceptions list of python exceptions, e.g. { PyExc_ValueError, PyExc_TypeError } | |
* @param params optional parameters to callback() | |
* @return decltype - return value of the callback() | |
* | |
* Example: | |
* | |
* const auto exceptions = { PyExc_KeyError, PyExc_ValueError }; | |
* const auto callback = []() { return py::dict()["key"]; }; // throws KeyError when called | |
* | |
* try | |
* { | |
* auto result = translate<std::exception>( callback, exceptions ); | |
* } | |
* catch( const std::exception& ) | |
* { | |
* std::cout << "key error occured" << std::endl; | |
* } | |
* | |
*/ | |
template<typename EXC, typename CALLBACK, typename ITERABLE, typename... Params> | |
inline auto translate( const CALLBACK& callback, const ITERABLE& exceptions, Params... params ) -> decltype( callback( params... ) ) | |
{ | |
try | |
{ | |
return callback( params... ); | |
} | |
catch( const boost::python::error_already_set& ) | |
{ | |
PyObject *exc, *value, *traceback; | |
PyErr_Fetch( &exc, &value, &traceback ); | |
for( PyObject* exc_ : exceptions ) | |
{ | |
if( PyErr_GivenExceptionMatches( exc, exc_ ) ) | |
{ | |
throw EXC(); | |
} | |
} | |
PyErr_Restore( exc, value, traceback ); | |
throw; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment