From: Jörg F. U. <joe...@un...> - 2009-06-24 14:15:11
|
I'm trying to build a C++ library doing the complex mathematics with a Python interpreter on top of it. In the application it occasionally occurs that exceptions are thrown. I'd like to catch these exceptions in Python, but a really would like to catch not the standard exceptions, but my own exception written in c++ and - via swig - wrapped to a Python exception. This is illustrated for a small example. I've got a class Matrix with a setValue method. If the position is out of the range of the allocated memory of the matrix, an exception of the type MyException is thrown. //File Matrix.h #ifndef MATRIX_H #define MATRIX_H #include <vector> #include "MyException.h" class Matrix { public: Matrix(int numRows_, int numColumns_, std::vector<double> entries_) { int numEntries = numRows_ * numColumns_; if (numEntries!=entries_.size()) throw MyException(std::string("Size of vector does not correspond to number of rows/colums\n")); entries = entries_; numRows = numRows_; numColumns = numColumns_; } void setValue(int row_, int col_, double value) { if (row_<0 || col_<0 || row_>=numRows || col_>=numColumns) { throw MyException(std::string("Position out of matrix dimension.")); } else entries[col_*numRows+row_] = value; } protected: int numRows, numColumns; std::vector<double> entries; }; #endif // MATRIX_H //File MyException.h #ifndef MYEXCEPTION_H #define MYEXCEPTION_H #include <string> #include <exception> class MyException : public std::exception { protected: std::string message; public: explicit MyException(const std::string& m) : message(m) {} virtual ~MyException() throw() {} virtual const char* what() const throw() { return message.c_str(); } }; #endif // MYEXCEPTION_H Using swig, I've created the wrapper files using the MyProject.i to create the module MyProject //file MyProject.i %module MyProject %{ /* Put headers and other declarations here */ #include "Matrix.h" #include "MyException.h" %} // user std::vectors on python level %include "std_vector.i" %include "std_string.i" // Instantiate templates used by example namespace std { %template(DoubleVector) vector<double>; } %include "MyException.h" %include "exception.i" %exception { try { $action } catch (MyException) { SWIG_exception_fail(SWIG_ValueError, "MyException"); } SWIG_CATCH_STDEXCEPT // catch std::exception catch (...) { SWIG_exception_fail(SWIG_UnknownError, "Unknown exception"); } } // provide the public interface %include "Matrix.h" Finally, I've applied this in a Python routine test.py //file test.py import MyProject doubleentries = MyProject.DoubleVector(0) doubleentries.resize(4) doubleentries[0] = 1 doubleentries[1] = 2 doubleentries[2] = 3 doubleentries[3] = 4.5 a=MyProject.Matrix(2,2,doubleentries) try: a.setValue(-1,-1,-1e12) except MyProject.MyException as e: print e print "That was MyException" except ValueError as e: print e print "That was a Value Error" except : print "Ohh, some undefined Error occured" What actually happens in the MyProject.i is, that the MyException is catched from the c++ file and swig creates a ValueError-exception, but instead of passing a ValueError-exception (or any other standard exception) to Python, I'd like to pass directly Myexception to Python. Myexception is via SWIG already a data type known in Python, but how can a actually modify the line catch (MyException) { SWIG_exception_fail(SWIG_ValueError, "MyException"); } to something like catch (MyException) { SWIG_exception_fail(SWIG_MyException "MyException"); } Thanks for the help Jörg F. |
From: William S F. <ws...@fu...> - 2009-06-25 21:14:49
|
Jörg F. Unger wrote: > I'm trying to build a C++ library doing the complex mathematics with a > Python interpreter on top of it. > > In the application it occasionally occurs that exceptions are thrown. > I'd like to catch these exceptions in Python, but a really would like to > catch not the standard exceptions, but my own exception written in c++ > and - via swig - wrapped to a Python exception. > > This is illustrated for a small example. > > I've got a class Matrix with a setValue method. If the position is out > of the range of the allocated memory of the matrix, an exception of the > type MyException is thrown. > > //File Matrix.h > #ifndef MATRIX_H > #define MATRIX_H > > #include <vector> > #include "MyException.h" > class Matrix > { > > public: > Matrix(int numRows_, int numColumns_, std::vector<double> entries_) > { > int numEntries = numRows_ * numColumns_; > if (numEntries!=entries_.size()) > throw MyException(std::string("Size of vector does not > correspond to number of rows/colums\n")); > entries = entries_; > numRows = numRows_; > numColumns = numColumns_; > } > > void setValue(int row_, int col_, double value) > { > if (row_<0 || col_<0 || row_>=numRows || col_>=numColumns) > { > throw MyException(std::string("Position out of matrix dimension.")); > } > else > entries[col_*numRows+row_] = value; > } > > protected: > int numRows, numColumns; > std::vector<double> entries; > }; > > > #endif // MATRIX_H > > > > > //File MyException.h > #ifndef MYEXCEPTION_H > #define MYEXCEPTION_H > > #include <string> > #include <exception> > > > class MyException : public std::exception > { > protected: > std::string message; > > public: > explicit MyException(const std::string& m) : message(m) {} > virtual ~MyException() throw() {} > virtual const char* what() const throw() > { > return message.c_str(); > } > }; > > #endif // MYEXCEPTION_H > > > Using swig, I've created the wrapper files using the MyProject.i to > create the module MyProject > > //file MyProject.i > %module MyProject > %{ > /* Put headers and other declarations here */ > #include "Matrix.h" > #include "MyException.h" > %} > > // user std::vectors on python level > %include "std_vector.i" > %include "std_string.i" > > // Instantiate templates used by example > namespace std > { > %template(DoubleVector) vector<double>; > } > > %include "MyException.h" > %include "exception.i" > > %exception > { > try > { > $action > } > catch (MyException) > { > SWIG_exception_fail(SWIG_ValueError, "MyException"); > } > > SWIG_CATCH_STDEXCEPT // catch std::exception > catch (...) > { > SWIG_exception_fail(SWIG_UnknownError, "Unknown exception"); > } > } > > // provide the public interface > %include "Matrix.h" > > > Finally, I've applied this in a Python routine test.py > > //file test.py > import MyProject > > doubleentries = MyProject.DoubleVector(0) > doubleentries.resize(4) > doubleentries[0] = 1 > doubleentries[1] = 2 > doubleentries[2] = 3 > doubleentries[3] = 4.5 > > a=MyProject.Matrix(2,2,doubleentries) > try: > a.setValue(-1,-1,-1e12) > > except MyProject.MyException as e: > print e > print "That was MyException" > except ValueError as e: > print e > print "That was a Value Error" > except : > print "Ohh, some undefined Error occured" > > > What actually happens in the MyProject.i is, that the MyException is > catched from the c++ file and swig creates a ValueError-exception, but > instead of passing a ValueError-exception (or any other standard > exception) to Python, I'd like to pass directly Myexception to Python. > Myexception is via SWIG already a data type known in Python, but how can > a actually modify the line > catch (MyException) > { > SWIG_exception_fail(SWIG_ValueError, "MyException"); > } > > to something like > catch (MyException) > { > SWIG_exception_fail(SWIG_MyException "MyException"); > } > The example in Examples/python/exceptproxy seems to do what you want. William |
From: Jörg F. U. <joe...@un...> - 2009-06-26 07:50:25
|
William S Fulton wrote: > Jörg F. Unger wrote: >> I'm trying to build a C++ library doing the complex mathematics with a >> Python interpreter on top of it. >> >> In the application it occasionally occurs that exceptions are thrown. >> I'd like to catch these exceptions in Python, but a really would like to >> catch not the standard exceptions, but my own exception written in c++ >> and - via swig - wrapped to a Python exception. >> >> This is illustrated for a small example. >> >> I've got a class Matrix with a setValue method. If the position is out >> of the range of the allocated memory of the matrix, an exception of the >> type MyException is thrown. >> >> //File Matrix.h >> #ifndef MATRIX_H >> #define MATRIX_H >> >> #include <vector> >> #include "MyException.h" >> class Matrix >> { >> >> public: >> Matrix(int numRows_, int numColumns_, std::vector<double> entries_) >> { >> int numEntries = numRows_ * numColumns_; >> if (numEntries!=entries_.size()) >> throw MyException(std::string("Size of vector does not >> correspond to number of rows/colums\n")); >> entries = entries_; >> numRows = numRows_; >> numColumns = numColumns_; >> } >> >> void setValue(int row_, int col_, double value) >> { >> if (row_<0 || col_<0 || row_>=numRows || col_>=numColumns) >> { >> throw MyException(std::string("Position out of matrix >> dimension.")); >> } >> else >> entries[col_*numRows+row_] = value; >> } >> >> protected: >> int numRows, numColumns; >> std::vector<double> entries; >> }; >> >> >> #endif // MATRIX_H >> >> >> >> >> //File MyException.h >> #ifndef MYEXCEPTION_H >> #define MYEXCEPTION_H >> >> #include <string> >> #include <exception> >> >> >> class MyException : public std::exception >> { >> protected: >> std::string message; >> >> public: >> explicit MyException(const std::string& m) : message(m) {} >> virtual ~MyException() throw() {} >> virtual const char* what() const throw() >> { >> return message.c_str(); >> } >> }; >> >> #endif // MYEXCEPTION_H >> >> >> Using swig, I've created the wrapper files using the MyProject.i to >> create the module MyProject >> >> //file MyProject.i >> %module MyProject >> %{ >> /* Put headers and other declarations here */ >> #include "Matrix.h" >> #include "MyException.h" >> %} >> >> // user std::vectors on python level >> %include "std_vector.i" >> %include "std_string.i" >> >> // Instantiate templates used by example >> namespace std >> { >> %template(DoubleVector) vector<double>; >> } >> >> %include "MyException.h" >> %include "exception.i" >> >> %exception >> { >> try >> { >> $action >> } >> catch (MyException) >> { >> SWIG_exception_fail(SWIG_ValueError, "MyException"); >> } >> >> SWIG_CATCH_STDEXCEPT // catch std::exception >> catch (...) >> { >> SWIG_exception_fail(SWIG_UnknownError, "Unknown exception"); >> } >> } >> >> // provide the public interface >> %include "Matrix.h" >> >> >> Finally, I've applied this in a Python routine test.py >> >> //file test.py >> import MyProject >> >> doubleentries = MyProject.DoubleVector(0) >> doubleentries.resize(4) >> doubleentries[0] = 1 >> doubleentries[1] = 2 >> doubleentries[2] = 3 >> doubleentries[3] = 4.5 >> >> a=MyProject.Matrix(2,2,doubleentries) >> try: >> a.setValue(-1,-1,-1e12) >> >> except MyProject.MyException as e: >> print e >> print "That was MyException" >> except ValueError as e: >> print e >> print "That was a Value Error" >> except : >> print "Ohh, some undefined Error occured" >> >> >> What actually happens in the MyProject.i is, that the MyException is >> catched from the c++ file and swig creates a ValueError-exception, but >> instead of passing a ValueError-exception (or any other standard >> exception) to Python, I'd like to pass directly Myexception to Python. >> Myexception is via SWIG already a data type known in Python, but how can >> a actually modify the line >> catch (MyException) >> { >> SWIG_exception_fail(SWIG_ValueError, "MyException"); >> } >> >> to something like >> catch (MyException) >> { >> SWIG_exception_fail(SWIG_MyException "MyException"); >> } >> > The example in Examples/python/exceptproxy seems to do what you want. > > William It worked pretty good - thanks for the answer. Jörg F. |