Exheredludis/python/exception.hh
Wouter van Kesteren 82a9e92b64 throw() -> noexcept
Change-Id: I461abfda8b7297c1bd04f1090f8d58fa96364616
Reviewed-on: https://galileo.mailstation.de/gerrit/1892
Reviewed-by: Saleem Abdulrasool <compnerd@compnerd.org>
Reviewed-by: Kylie McClain <somasis@exherbo.org>
2015-08-21 17:19:40 +02:00

158 lines
5.5 KiB
C++

/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
* Copyright (c) 2007 Piotr JaroszyƄski
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
* Public License version 2, as published by the Free Software Foundation.
*
* Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PALUDIS_GUARD_PYTHON_EXCEPTION_HH
#define PALUDIS_GUARD_PYTHON_EXCEPTION_HH 1
#include <paludis/util/pimp.hh>
#include <paludis/util/exception.hh>
#include <paludis/util/singleton-impl.hh>
#include <boost/python.hpp>
#include <memory>
#include <functional>
namespace paludis
{
namespace python
{
class RegisteredExceptionBase
{
public:
virtual ~RegisteredExceptionBase() = 0;
virtual PyObject * get_py_exception() const = 0;
};
template <typename Ex_>
class RegisteredException :
public RegisteredExceptionBase
{
private:
const std::string _name;
const std::string _longname;
PyObject * _e;
public:
RegisteredException(const std::string & name, const std::string & doc, PyObject * base);
void translator(const Ex_ & x) const;
PyObject *
get_py_exception() const
{
return _e;
}
};
template <class Ex_>
RegisteredException<Ex_>::RegisteredException(const std::string & name,
const std::string & doc, PyObject * base) :
_name(name),
_longname("paludis." + name),
_e(PyErr_NewException(const_cast<char*>(_longname.c_str()), base, NULL))
{
PyModule_AddObject(boost::python::detail::current_scope, const_cast<char*>(_name.c_str()), _e);
PyObject * doc_string =
#if PY_MAJOR_VERSION < 3
PyString_FromString(doc.c_str());
# else
PyUnicode_FromString(doc.c_str());
# endif
PyObject_SetAttrString(_e, "__doc__", doc_string);
boost::python::register_exception_translator<Ex_>(
std::bind(std::mem_fn(&RegisteredException<Ex_>::translator), this, std::placeholders::_1));
}
template <class Ex_>
void
RegisteredException<Ex_>::translator(const Ex_ & x) const
{
#if PY_MAJOR_VERSION < 3
PyObject * backtrace = PyString_FromString(x.backtrace("\n").c_str());
PyObject * message = PyString_FromString(x.message().c_str());
PyObject * what = PyString_FromString(x.what());
#else
PyObject * backtrace = PyUnicode_FromString(x.backtrace("\n").c_str());
PyObject * message = PyUnicode_FromString(x.message().c_str());
PyObject * what = PyUnicode_FromString(x.what());
#endif
PyObject_SetAttrString(_e, "backtrace", backtrace);
PyObject_SetAttrString(_e, "message", message);
PyObject_SetAttrString(_e, "what", what);
PyErr_SetString(_e, x.message().c_str());
}
class PALUDIS_VISIBLE ExceptionRegister :
public Singleton<ExceptionRegister>
{
friend class Singleton<ExceptionRegister>;
private:
Pimp<ExceptionRegister> _imp;
ExceptionRegister();
void add_map_item(const std::string & name, std::shared_ptr<RegisteredExceptionBase>);
PyObject * get_py_exception(const std::string & name);
public:
~ExceptionRegister();
template <typename Ex_>
void add_exception(const std::string & name, const std::string & doc)
{
add_map_item(name, std::shared_ptr<RegisteredExceptionBase>(
new RegisteredException<Ex_>(name, doc, 0)));
}
template <typename Ex_>
void add_exception(const std::string & name, const std::string & base, const std::string & doc)
{
add_map_item(name, std::shared_ptr<RegisteredExceptionBase>(
new RegisteredException<Ex_>(name, doc, get_py_exception(base))));
}
};
class PALUDIS_VISIBLE PythonError :
public Exception
{
public:
PythonError(const std::string & message) noexcept;
};
class PALUDIS_VISIBLE PythonMethodNotImplemented :
public PythonError
{
public:
PythonMethodNotImplemented(const std::string & class_name,
const std::string & function_name) noexcept;
};
class PALUDIS_VISIBLE PythonContainerConversionError :
public PythonError
{
public:
PythonContainerConversionError(const std::string & class_name,
const std::string & container_name, const std::string & o_type) noexcept;
};
}
}
#endif