[C++-sig] A first glance at what could be the boost::python exception system

Berthold Höllmann hoel at germanlloyd.org
Fri Jul 26 16:16:01 CEST 2002


Hello all,

David asked if I coud implement the C++ wrapper system for the Python
exception system. Now, it is friday afternoon again and I won't have
time to work on this over the weekend. The only test I did was sending
this through the compiler (g++ 3.1). How do I enable "str(exception)"
doing someting meaningfull? Another facility that is missing is a
routine checking for a set Python exception and returning/raising the
apropriate C++ counterpart. Is there any idea how this could be
accomplished without a huge set of if/else if's and in a way easy
extensible for user defined exceptions? I tried to map the class
hierarchy found with

>python
Python 2.2.1 (#3, Jun  4 2002, 09:47:49) 
[GCC 3.1] on sunos5
Type "help", "copyright", "credits" or "license" for more information.
>>> import exceptions
>>> help(exceptions)

I left out the warnings, because I don't think they should be mapped
to C++ Exceptions, but they could be added. I hope it's OK to attach
"exceptions.hpp" and "exceptions.cpp".

Greetings

Berthold



This email contains confidential information for the exclusive attention
of the intended addressee. Any access of third parties to this email is
unauthorized. Any use of this email by not intended recipients like
copying, distribution, disclosure etc. is prohibited and may be
unlawful. When addressed to our clients the content of this email is
subject to the General Terms and Conditions of GL's Group of Companies
applicable at the date of this email. 

GL's Group of Companies does not warrant and/or guarantee that this
message at the moment of receipt is authentic, correct and its
communication free of errors, interruption etc. 
-------------- next part --------------
// Copyright Berthold Höllmann 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.

#if !defined _HOEL20020726AA_H
#define _HOEL20020726AA_H

#include <Python.h>

#define BOOST_PYTHON_V2 1

#include <boost/python/object_core.hpp>

#include <iostream>

namespace boost {
  namespace python {
    namespace detail {
      // Standard Exceptions wrapper
      template <PyObject** E>
      class python_exception
      {
      public:
        BOOST_PYTHON_DECL python_exception(const object &_msg = object(Py_None)) :
          msg(_msg)
        {
        }
        object BOOST_PYTHON_DECL get()
        {
          PyObject *err = PyInstance_New(oclass, NULL, NULL);
          bool res = PyErr_GivenExceptionMatches(err, PyExc);
          Py_DECREF(err);
          return res;
        };
        bool BOOST_PYTHON_DECL operator== (const PyObject *other) const
        {
          return PyErr_GivenExceptionMatches(other, PyExc);
        }
        bool BOOST_PYTHON_DECL operator== (const python_exception &other) const
        {
          PyObject *oclass = other.get();
          PyObject *err = PyInstance_New(oclass, NULL, NULL);
          bool res = PyErr_GivenExceptionMatches(err, PyExc);
          Py_DECREF(err);
          return res;
        }
      protected:
        static BOOST_PYTHON_DECL object PyExc;
        object msg;
      };

      template <PyTypeObject** E>
      object python_exception<E>::PyExc(*E);
    }

    class exception :
      public detail::python_exception<&PyExc_Exception>
    {
    public:
      BOOST_PYTHON_DECL exception(const object &_msg =
                                  object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_Exception>(_msg)
      {
      }
    };
    class system_exit :
      public detail::python_exception<&PyExc_SystemExit>
    {
    public:
      BOOST_PYTHON_DECL system_exit(const object &_msg =
                                    object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_SystemExit>(_msg)
      {
      }
    };

    class stop_iteration :
      public detail::python_exception<&PyExc_StopIteration>
    {
    public:
      BOOST_PYTHON_DECL stop_iteration(const object &_msg =
                                       object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_StopIteration>(_msg)
      {
      }
    };

    class standard_error :
      public detail::python_exception<&PyExc_StandardError>
    {
    public:
      BOOST_PYTHON_DECL standard_error(const object &_msg =
                                       object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_StandardError>(_msg)
      {
      }
    };

    class keyboard_interrupt :
      public standard_error,
      public detail::python_exception<&PyExc_KeyboardInterrupt>
    {
    public:
      BOOST_PYTHON_DECL keyboard_interrupt(const object &_msg =
                                           object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_KeyboardInterrupt>(_msg)
      {
      }
    };

    class import_error :
      public standard_error,
      public detail::python_exception<&PyExc_ImportError>
    {
    public:
      BOOST_PYTHON_DECL import_error(const object &_msg =
                                     object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_ImportError>(_msg)
      {
      }
    };

    class environment_error :
      public standard_error,
      public detail::python_exception<&PyExc_EnvironmentError>
    {
    public:
      BOOST_PYTHON_DECL environment_error(const object &_msg =
                                          object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_EnvironmentError>(_msg)
      {
      }
    };

    class io_error :
      public environment_error,
      public detail::python_exception<&PyExc_IOError>
    {
    public:
      BOOST_PYTHON_DECL io_error(const object &_msg =
                                 object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_IOError>(_msg)
      {
      }
    };

    class os_error :
      public environment_error,
      public detail::python_exception<&PyExc_OSError>
    {
    public:
      BOOST_PYTHON_DECL os_error(const object &_msg =
                                 object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_OSError>(_msg)
      {
      }
    };
#ifdef MS_WINDOWS
    class windows_error :
      public os_error,
      public detail::python_exception<&PyExc_WindowsError>
    {
    public:
      BOOST_PYTHON_DECL windows_error(const object &_msg =
                                      object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_WindowsError>(_msg)
      {
      }
    };
#endif
    class eof_error :
      public standard_error,
      public detail::python_exception<&PyExc_EOFError>
    {
    public:
      BOOST_PYTHON_DECL eof_error(const object &_msg =
                                  object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_EOFError>(_msg)
      {
      }
    };

    class runtime_error :
      public standard_error,
      public detail::python_exception<&PyExc_RuntimeError>
    {
    public:
      BOOST_PYTHON_DECL runtime_error(const object &_msg =
                                      object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_RuntimeError>(_msg)
      {
      }
    };
    class not_implemented_error :
      public runtime_error,
      public detail::python_exception<&PyExc_NotImplementedError>
    {
    public:
      BOOST_PYTHON_DECL not_implemented_error(const object &_msg =
                                              object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_NotImplementedError>(_msg)
      {
      }
    };
    class name_error :
      public standard_error,
      public detail::python_exception<&PyExc_NameError>
    {
    public:
      BOOST_PYTHON_DECL name_error(const object &_msg =
                                   object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_NameError>(_msg)
      {
      }
    };
    class unbound_local_error :
      public name_error,
      public detail::python_exception<&PyExc_UnboundLocalError>
    {
    public:
      BOOST_PYTHON_DECL unbound_local_error(const object &_msg =
                                            object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_UnboundLocalError>(_msg)
      {
      }
    };
    class attribute_error :
      public standard_error,
      public detail::python_exception<&PyExc_AttributeError>
    {
    public:
      BOOST_PYTHON_DECL attribute_error(const object &_msg =
                                        object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_AttributeError>(_msg)
      {
      }
    };
    class syntax_error :
      public standard_error,
      public detail::python_exception<&PyExc_SyntaxError>
    {
    public:
      BOOST_PYTHON_DECL syntax_error(const object &_msg =
                                     object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_SyntaxError>(_msg)
      {
      }
    };
    class indentation_error :
      public  syntax_error,
      public detail::python_exception<&PyExc_IndentationError>
    {
    public:
      BOOST_PYTHON_DECL indentation_error(const object &_msg =
                                          object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_IndentationError>(_msg)
      {
      }
    };
    class tab_error :
      public indentation_error,
      public detail::python_exception<&PyExc_TabError>
    {
    public:
      BOOST_PYTHON_DECL tab_error(const object &_msg =
                                  object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_TabError>(_msg)
      {
      }
    };
    class type_error :
      public standard_error,
      public detail::python_exception<&PyExc_TypeError>
    {
    public:
      BOOST_PYTHON_DECL type_error(const object &_msg =
                                   object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_TypeError>(_msg)
      {
      }
    };
    class assertion_error :
      public standard_error,
      public detail::python_exception<&PyExc_AssertionError>
    {
    public:
      BOOST_PYTHON_DECL assertion_error(const object &_msg =
                                        object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_AssertionError>(_msg)
      {
      }
    };
    class lookup_error :
      public standard_error,
      public detail::python_exception<&PyExc_LookupError>
    {
    public:
      BOOST_PYTHON_DECL lookup_error(const object &_msg =
                                     object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_LookupError>(_msg)
      {
      }
    };
    class index_error :
      public lookup_error,
      public detail::python_exception<&PyExc_IndexError>
    {
    public:
      BOOST_PYTHON_DECL index_error(const object &_msg =
                                    object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_IndexError>(_msg)
      {
      }
    };
    class key_error :
      public lookup_error,
      public detail::python_exception<&PyExc_KeyError>
    {
    public:
      BOOST_PYTHON_DECL key_error(const object &_msg =
                                  object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_KeyError>(_msg)
      {
      }
    };
    class arithmetic_error :
      public standard_error,
      public detail::python_exception<&PyExc_ArithmeticError>
    {
    public:
      BOOST_PYTHON_DECL arithmetic_error(const object &_msg =
                                         object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_ArithmeticError>(_msg)
      {
      }
    };
    class overflow_error :
      public arithmetic_error,
      public detail::python_exception<&PyExc_OverflowError>
    {
    public:
      BOOST_PYTHON_DECL overflow_error(const object &_msg =
                                       object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_OverflowError>(_msg)
      {
      }
    };
    class zero_division_error :
      public arithmetic_error,
      public detail::python_exception<&PyExc_ZeroDivisionError>
    {
    public:
      BOOST_PYTHON_DECL zero_division_error(const object &_msg =
                                            object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_ZeroDivisionError>(_msg)
      {
      }
    };
    class floating_point_error :
      public arithmetic_error,
      public detail::python_exception<&PyExc_FloatingPointError>
    {
    public:
      BOOST_PYTHON_DECL floating_point_error(const object &_msg =
                                             object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_FloatingPointError>(_msg)
      {
      }
    };
    class value_error :
      public standard_error,
      public detail::python_exception<&PyExc_ValueError>
    {
    public:
      BOOST_PYTHON_DECL value_error(const object &_msg =
                                    object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_ValueError>(_msg)
      {
      }
    };
    class unicode_error :
      public value_error,
      public detail::python_exception<&PyExc_UnicodeError>
    {
    public:
      BOOST_PYTHON_DECL unicode_error(const object &_msg =
                                      object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_UnicodeError>(_msg)
      {
      }
    };
    class reference_error :
      public standard_error,
      public detail::python_exception<&PyExc_ReferenceError>
    {
    public:
      BOOST_PYTHON_DECL reference_error(const object &_msg =
                                        object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_ReferenceError>(_msg)
      {
      }
    };
    class system_error :
      public standard_error,
      public detail::python_exception<&PyExc_SystemError>
    {
    public:
      BOOST_PYTHON_DECL system_error(const object &_msg =
                                     object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_SystemError>(_msg)
      {
      }
    };
    class memory_error :
      public standard_error,
      public detail::python_exception<&PyExc_MemoryError>
    {
    public:
      BOOST_PYTHON_DECL memory_error(const object &_msg =
                                     object(detail::borrowed_reference(Py_None))) :
        detail::python_exception<&PyExc_MemoryError>(_msg)
      {
      }
    };

    BOOST_PYTHON_DECL void
    throw_exception(const object &_msg =
                    object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_system_exit(const object &_msg =
                      object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_stop_iteration(const object &_msg =
                         object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_standard_error(const object &_msg =
                         object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_keyboard_interrupt(const object &_msg =
                             object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_import_error(const object &_msg =
                       object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_environment_error(const object &_msg =
                            object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_io_error(const object &_msg =
                   object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL
    void throw_os_error(const object &_msg =
                        object(detail::borrowed_reference(Py_None)));
#ifdef MS_WINDOWS
    BOOST_PYTHON_DECL void
    throw_windows_error(const object &_msg =
                        object(detail::borrowed_reference(Py_None)));
#endif
    BOOST_PYTHON_DECL void
    throw_eof_error(const object &_msg =
                    object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_runtime_error(const object &_msg =
                        object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_not_implemented_error(const object &_msg =
                                object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_name_error(const object &_msg =
                     object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_unbound_local_error(const object &_msg =
                              object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_attribute_error(const object &_msg =
                          object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_syntax_error(const object &_msg =
                       object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_indentation_error(const object &_msg =
                            object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_tab_error(const object &_msg =
                    object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_type_error(const object &_msg =
                     object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_assertion_error(const object &_msg =
                          object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_lookup_error(const object &_msg =
                       object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_index_error(const object &_msg =
                      object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_key_error(const object &_msg =
                    object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_arithmetic_error(const object &_msg =
                           object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_overflow_error(const object &_msg =
                         object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_zero_division_error(const object &_msg =
                              object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_floating_point_error(const object &_msg =
                               object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_value_error(const object &_msg =
                      object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_unicode_error(const object &_msg =
                        object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_reference_error(const object &_msg =
                          object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_system_error(const object &_msg =
                       object(detail::borrowed_reference(Py_None)));
    BOOST_PYTHON_DECL void
    throw_memory_error(const object &_msg =
                       object(detail::borrowed_reference(Py_None)));

  }
}

#endif // _HOEL20020726AA_H
-------------- next part --------------
// Copyright Berthold Höllmann 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.


#include <exceptions.hpp>

namespace boost {
  namespace python {

    void BOOST_PYTHON_DECL throw_exception(const object &msg)
    {
      throw exception(msg);
    }
    void BOOST_PYTHON_DECL throw_system_exit(const object &msg)
    {
      throw system_exit(msg);
    }
    void BOOST_PYTHON_DECL throw_stop_iteration(const object &msg)
    {
      throw stop_iteration(msg);
    }
    void BOOST_PYTHON_DECL throw_standard_error(const object &msg)
    {
      throw standard_error(msg);
    }
    void BOOST_PYTHON_DECL throw_keyboard_interrupt(const object &msg)
    {
      throw keyboard_interrupt(msg);
    }
    void BOOST_PYTHON_DECL throw_import_error(const object &msg)
    {
      throw import_error(msg);
    }
    void BOOST_PYTHON_DECL throw_environment_error(const object &msg)
    {
      throw environment_error(msg);
    }
    void BOOST_PYTHON_DECL throw_io_error(const object &msg)
    {
      throw io_error(msg);
    }
    void BOOST_PYTHON_DECL throw_os_error(const object &msg)
    {
      throw os_error(msg);
    }
#ifdef MS_WINDOWS
    void BOOST_PYTHON_DECL throw_windows_error(const object &msg)
    {
      throw windows_error(msg);
    }
#endif
    void BOOST_PYTHON_DECL throw_eof_error(const object &msg)
    {
      throw eof_error(msg);
    }
    void BOOST_PYTHON_DECL throw_runtime_error(const object &msg)
    {
      throw runtime_error(msg);
    }
    void BOOST_PYTHON_DECL throw_not_implemented_error(const object &msg)
    {
      throw not_implemented_error(msg);
    }
    void BOOST_PYTHON_DECL throw_name_error(const object &msg)
    {
      throw name_error(msg);
    }
    void BOOST_PYTHON_DECL throw_unbound_local_error(const object &msg)
    {
      throw unbound_local_error(msg);
    }
    void BOOST_PYTHON_DECL throw_attribute_error(const object &msg)
    {
      throw attribute_error(msg);
    }
    void BOOST_PYTHON_DECL throw_syntax_error(const object &msg)
    {
      throw syntax_error(msg);
    }
    void BOOST_PYTHON_DECL throw_indentation_error(const object &msg)
    {
      throw indentation_error(msg);
    }
    void BOOST_PYTHON_DECL throw_tab_error(const object &msg)
    {
      throw tab_error(msg);
    }
    void BOOST_PYTHON_DECL throw_type_error(const object &msg)
    {
      throw type_error(msg);
    }
    void BOOST_PYTHON_DECL throw_assertion_error(const object &msg)
    {
      throw assertion_error(msg);
    }
    void BOOST_PYTHON_DECL throw_lookup_error(const object &msg)
    {
      throw lookup_error(msg);
    }
    void BOOST_PYTHON_DECL throw_index_error(const object &msg)
    {
      throw index_error(msg);
    }
    void BOOST_PYTHON_DECL throw_key_error(const object &msg)
    {
      throw key_error(msg);
    }
    void BOOST_PYTHON_DECL throw_arithmetic_error(const object &msg)
    {
      throw arithmetic_error(msg);
    }
    void BOOST_PYTHON_DECL throw_overflow_error(const object &msg)
    {
      throw overflow_error(msg);
    }
    void BOOST_PYTHON_DECL throw_zero_division_error(const object &msg)
    {
      throw zero_division_error(msg);
    }
    void BOOST_PYTHON_DECL throw_floating_point_error(const object &msg)
    {
      throw floating_point_error(msg);
    }
    void BOOST_PYTHON_DECL throw_value_error(const object &msg)
    {
      throw value_error(msg);
    }
    void BOOST_PYTHON_DECL throw_unicode_error(const object &msg)
    {
      throw unicode_error(msg);
    }
    void BOOST_PYTHON_DECL throw_reference_error(const object &msg)
    {
      throw reference_error(msg);
    }
    void BOOST_PYTHON_DECL throw_system_error(const object &msg)
    {
      throw system_error(msg);
    }
    void BOOST_PYTHON_DECL throw_memory_error(const object &msg)
    {
      throw memory_error(msg);
    }
  }
} // namespace boost::python
-------------- next part --------------

-- 
Dipl.-Ing. Berthold Höllmann   __   Address:
hoel at germanlloyd.org        G /  \ L Germanischer Lloyd
phone: +49-40-36149-7374    -+----+- Vorsetzen 32/35    P.O.Box 111606
fax  : +49-40-36149-7320      \__/   D-20459 Hamburg    D-20416 Hamburg


More information about the Cplusplus-sig mailing list