throw exception in c++ and return it to python

View: New views
3 Messages — Rating Filter:   Alert me  

throw exception in c++ and return it to python

by "Jörg F. Unger" :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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.

------------------------------------------------------------------------------
_______________________________________________
Swig-user mailing list
Swig-user@...
https://lists.sourceforge.net/lists/listinfo/swig-user

Re: throw exception in c++ and return it to python

by wsfulton :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

------------------------------------------------------------------------------
_______________________________________________
Swig-user mailing list
Swig-user@...
https://lists.sourceforge.net/lists/listinfo/swig-user

Re: throw exception in c++ and return it to python

by "Jörg F. Unger" :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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.



------------------------------------------------------------------------------
_______________________________________________
Swig-user mailing list
Swig-user@...
https://lists.sourceforge.net/lists/listinfo/swig-user