aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Piotr Jaroszyński <peper@gentoo.org> 2007-05-22 11:34:11 +0000
committerAvatar Piotr Jaroszyński <peper@gentoo.org> 2007-05-22 11:34:11 +0000
commit69b524f747b352b99236551556d036d643e9b3f4 (patch)
treeabb492d9deb25b689a53d0f94a3435aa3cc1b073
parenta64e75dfa05f531abc03cc48df59e27b14302bfd (diff)
downloadpaludis-69b524f747b352b99236551556d036d643e9b3f4.tar.gz
paludis-69b524f747b352b99236551556d036d643e9b3f4.tar.xz
(python) Expose hierarchy of the exceptions.
-rw-r--r--python/Makefile.am2
-rw-r--r--python/dep_spec.cc4
-rw-r--r--python/environment.cc20
-rw-r--r--python/exception.cc74
-rw-r--r--python/exception.hh126
-rw-r--r--python/fs_entry.cc4
-rw-r--r--python/name.cc36
-rw-r--r--python/package_database.cc24
-rwxr-xr-xpython/paludis_python.hh40
-rw-r--r--python/paludis_python_so.cc2
-rw-r--r--python/portage_dep_parser.cc10
-rw-r--r--python/repository.cc25
-rw-r--r--python/version_operator.cc4
-rw-r--r--python/version_spec.cc4
14 files changed, 271 insertions, 104 deletions
diff --git a/python/Makefile.am b/python/Makefile.am
index cdcbc9c..9872729 100644
--- a/python/Makefile.am
+++ b/python/Makefile.am
@@ -39,6 +39,7 @@ IF_PYTHON_TESTS = \
IF_PYTHON_QA_TESTS =
IF_PYTHON_SOURCES = \
+ exception.cc \
contents.cc \
dep_spec.cc \
environment.cc \
@@ -59,6 +60,7 @@ IF_PYTHON_QA_SOURCES =
EXTRA_DIST = $(IF_PYTHON_TESTS) $(IF_PYTHON_SOURCES) \
$(IF_PYTHON_QA_TESTS) $(IF_PYTHON_QA_SOURCES) \
+ exception.hh \
paludis_python.hh \
paludis_python_so.cc \
environment_TEST_setup.sh environment_TEST_cleanup.sh \
diff --git a/python/dep_spec.cc b/python/dep_spec.cc
index 12af21c..2375583 100644
--- a/python/dep_spec.cc
+++ b/python/dep_spec.cc
@@ -27,8 +27,8 @@ namespace bp = boost::python;
void PALUDIS_VISIBLE expose_dep_spec()
{
- static register_exception<PackageDepSpecError>
- PackageDepSpecError("PackageDepSpecError");
+ ExceptionRegister::get_instance()->add_exception<PackageDepSpecError>
+ ("PackageDepSpecError", "BaseException");
enum_auto("PackageDepSpecParseMode", last_pds_pm);
diff --git a/python/environment.cc b/python/environment.cc
index bfc24fa..8185b7b 100644
--- a/python/environment.cc
+++ b/python/environment.cc
@@ -43,16 +43,16 @@ struct NoConfigEnvironmentWrapper :
void PALUDIS_VISIBLE expose_environment()
{
- static register_exception<NoSuchEnvironmentTypeError>
- NoSuchEnvironmentTypeError("NoSuchEnvironmentTypeError");
- static register_exception<PaludisEnvironmentSoDirNotADirectoryError>
- PaludisEnvironmentSoDirNotADirectoryError("PaludisEnvironmentSoDirNotADirectoryError");
- static register_exception<PaludisEnvironmentSoDirCannotDlopenError>
- PaludisEnvironmentSoDirCannotDlopenError("PaludisEnvironmentSoDirCannotDlopenError");
- static register_exception<PaludisConfigError>
- PaludisConfigError("PaludisConfigError");
- static register_exception<PaludisConfigNoDirectoryError>
- PaludisConfigNoDirectoryError("PaludisConfigNoDirectoryError");
+ ExceptionRegister::get_instance()->add_exception<NoSuchEnvironmentTypeError>
+ ("NoSuchEnvironmentTypeError", "ConfigurationError");
+ ExceptionRegister::get_instance()->add_exception<PaludisEnvironmentSoDirNotADirectoryError>
+ ("PaludisEnvironmentSoDirNotADirectoryError", "BaseException");
+ ExceptionRegister::get_instance()->add_exception<PaludisEnvironmentSoDirCannotDlopenError>
+ ("PaludisEnvironmentSoDirCannotDlopenError", "BaseException");
+ ExceptionRegister::get_instance()->add_exception<PaludisConfigError>
+ ("PaludisConfigError", "ConfigurationError");
+ ExceptionRegister::get_instance()->add_exception<PaludisConfigNoDirectoryError>
+ ("PaludisConfigNoDirectoryError", "PaludisConfigError");
bp::class_<EnvironmentMaker, boost::noncopyable> em("EnvironmentMaker",
"Virtual constructor for environments.",
diff --git a/python/exception.cc b/python/exception.cc
new file mode 100644
index 0000000..c95b0d5
--- /dev/null
+++ b/python/exception.cc
@@ -0,0 +1,74 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Piotr Jaroszyński <peper@gentoo.org>
+ *
+ * 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
+ */
+
+#include "exception.hh"
+
+#include <map>
+
+using namespace paludis;
+using namespace paludis::python;
+namespace bp = boost::python;
+
+RegisteredExceptionBase::~RegisteredExceptionBase()
+{
+}
+
+namespace paludis
+{
+ template<>
+ struct Implementation<ExceptionRegister>
+ {
+ std::map<std::string, tr1::shared_ptr<RegisteredExceptionBase> > exceptions;
+ };
+ typedef std::map<std::string, tr1::shared_ptr<RegisteredExceptionBase> >::iterator ExceptionsIterator;
+}
+
+ExceptionRegister::ExceptionRegister() :
+ PrivateImplementationPattern<ExceptionRegister>(new Implementation<ExceptionRegister>)
+{
+}
+
+ExceptionRegister::~ExceptionRegister()
+{
+}
+
+void
+ExceptionRegister::add_map_item(const std::string & name, tr1::shared_ptr<RegisteredExceptionBase> p)
+{
+ _imp->exceptions.insert(std::make_pair(name, p));
+}
+
+PyObject *
+ExceptionRegister::get_py_exception(const std::string & name)
+{
+ ExceptionsIterator i(_imp->exceptions.find(name));
+ if (i != _imp->exceptions.end())
+ return i->second->get_py_exception();
+ else
+ return NULL;
+}
+
+void PALUDIS_VISIBLE expose_exception()
+{
+ ExceptionRegister::get_instance()->add_exception<Exception>("BaseException");
+ ExceptionRegister::get_instance()->add_exception<InternalError>("InternalError", "BaseException");
+ ExceptionRegister::get_instance()->add_exception<NotAvailableError>("NotAvailableError", "BaseException");
+ ExceptionRegister::get_instance()->add_exception<NameError>("NameError", "BaseException");
+ ExceptionRegister::get_instance()->add_exception<ConfigurationError>("ConfigurationError", "BaseException");
+}
diff --git a/python/exception.hh b/python/exception.hh
new file mode 100644
index 0000000..eebdf28
--- /dev/null
+++ b/python/exception.hh
@@ -0,0 +1,126 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Piotr Jaroszyński <peper@gentoo.org>
+ *
+ * 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_PALUDIS_EXCEPTION_HH
+#define PALUDIS_GUARD_PYTHON_PALUDIS_EXCEPTION_HH 1
+
+#include <paludis/util/tr1_memory.hh>
+#include <paludis/util/tr1_functional.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/exception.hh>
+
+#include <boost/python.hpp>
+
+using namespace paludis;
+namespace bp = boost::python;
+
+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, 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, PyObject * base=NULL) :
+ _name(name),
+ _longname("paludis." + name),
+ _e(PyErr_NewException(const_cast<char*>(_longname.c_str()), base, NULL))
+ {
+ PyModule_AddObject(bp::detail::current_scope, const_cast<char*>(_name.c_str()), _e);
+ bp::register_exception_translator<Ex_>(
+ tr1::bind(tr1::mem_fn(&RegisteredException<Ex_>::translator),
+ this, tr1::placeholders::_1)
+ );
+ }
+
+ template <class Ex_>
+ void
+ RegisteredException<Ex_>::translator(const Ex_ & x) const
+ {
+ PyObject * backtrace = PyString_FromString(x.backtrace("\n").c_str());
+ PyObject * message = PyString_FromString(x.message().c_str());
+ PyObject * what = PyString_FromString(x.what());
+ 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 InstantiationPolicy<ExceptionRegister, instantiation_method::SingletonTag>,
+ private PrivateImplementationPattern<ExceptionRegister>
+ {
+ friend class InstantiationPolicy<ExceptionRegister, instantiation_method::SingletonTag>;
+
+ private:
+ ExceptionRegister();
+
+ void add_map_item(const std::string & name, tr1::shared_ptr<RegisteredExceptionBase>);
+ PyObject * get_py_exception(const std::string & name);
+
+ public:
+ ~ExceptionRegister();
+
+ template <typename Ex_>
+ void add_exception(const std::string & name)
+ {
+ add_map_item(name, tr1::shared_ptr<RegisteredExceptionBase>(
+ new RegisteredException<Ex_>(name)));
+ }
+
+ template <typename Ex_>
+ void add_exception(const std::string & name, const std::string & base)
+ {
+ add_map_item(name, tr1::shared_ptr<RegisteredExceptionBase>(
+ new RegisteredException<Ex_>(name, get_py_exception(base))));
+ }
+ };
+ }
+}
+
+#endif
+
diff --git a/python/fs_entry.cc b/python/fs_entry.cc
index d169941..fb9136d 100644
--- a/python/fs_entry.cc
+++ b/python/fs_entry.cc
@@ -27,8 +27,8 @@ namespace bp = boost::python;
void PALUDIS_VISIBLE expose_fs_entry()
{
- static register_exception<FSError>
- FSError("FSError");
+ ExceptionRegister::get_instance()->add_exception<FSError>
+ ("FSError", "BaseException");
bp::implicitly_convertible<std::string, FSEntry>();
bp::to_python_converter<FSEntry, to_string<FSEntry> >();
diff --git a/python/name.cc b/python/name.cc
index fffd144..a8e8f44 100644
--- a/python/name.cc
+++ b/python/name.cc
@@ -27,24 +27,24 @@ namespace bp = boost::python;
void PALUDIS_VISIBLE expose_name()
{
- static register_exception<PackageNamePartError>
- PackageNamePartError("PackageNamePartError");
- static register_exception<CategoryNamePartError>
- CategoryNamePartError("CategoryNamePartError");
- static register_exception<QualifiedPackageNameError>
- QualifiedPackageNameError("QualifiedPackageNameError");
- static register_exception<UseFlagNameError>
- UseFlagNameError("UseFlagNameError");
- static register_exception<IUseFlagNameError>
- IUseFlagNameError("IUseFlagNameError");
- static register_exception<SlotNameError>
- SlotNameError("SlotNameError");
- static register_exception<RepositoryNameError>
- RepositoryNameError("RepositoryNameError");
- static register_exception<KeywordNameError>
- KeywordNameError("KeywordNameError");
- static register_exception<SetNameError>
- SetNameError("SetNameError");
+ ExceptionRegister::get_instance()->add_exception<PackageNamePartError>
+ ("PackageNamePartError", "NameError");
+ ExceptionRegister::get_instance()->add_exception<CategoryNamePartError>
+ ("CategoryNamePartError", "NameError");
+ ExceptionRegister::get_instance()->add_exception<QualifiedPackageNameError>
+ ("QualifiedPackageNameError", "NameError");
+ ExceptionRegister::get_instance()->add_exception<UseFlagNameError>
+ ("UseFlagNameError", "NameError");
+ ExceptionRegister::get_instance()->add_exception<IUseFlagNameError>
+ ("IUseFlagNameError", "NameError");
+ ExceptionRegister::get_instance()->add_exception<SlotNameError>
+ ("SlotNameError", "NameError");
+ ExceptionRegister::get_instance()->add_exception<RepositoryNameError>
+ ("RepositoryNameError", "NameError");
+ ExceptionRegister::get_instance()->add_exception<KeywordNameError>
+ ("KeywordNameError", "NameError");
+ ExceptionRegister::get_instance()->add_exception<SetNameError>
+ ("SetNameError", "NameError");
class_validated<PackageNamePart>
pnp("PackageNamePart",
diff --git a/python/package_database.cc b/python/package_database.cc
index 39fb9da..574a113 100644
--- a/python/package_database.cc
+++ b/python/package_database.cc
@@ -32,18 +32,18 @@ namespace bp = boost::python;
void PALUDIS_VISIBLE expose_package_database()
{
- static register_exception<PackageDatabaseError>
- PackageDatabaseError("PackageDatabaseError");
- static register_exception<PackageDatabaseLookupError>
- PackageDatabaseLookupError("PackageDatabaseLookupError");
- static register_exception<AmbiguousPackageNameError>
- AmbiguousPackageNameError("AmbiguousPackageNameError");
- static register_exception<DuplicateRepositoryError>
- DuplicateRepositoryError("DuplicateRepositoryError");
- static register_exception<NoSuchPackageError>
- NoSuchPackageError("NoSuchPackageError");
- static register_exception<NoSuchRepositoryError>
- NoSuchRepositoryError("NoSuchRepositoryError");
+ ExceptionRegister::get_instance()->add_exception<PackageDatabaseError>
+ ("PackageDatabaseError", "BaseException");
+ ExceptionRegister::get_instance()->add_exception<DuplicateRepositoryError>
+ ("DuplicateRepositoryError", "PackageDatabaseError");
+ ExceptionRegister::get_instance()->add_exception<PackageDatabaseLookupError>
+ ("PackageDatabaseLookupError", "PackageDatabaseError");
+ ExceptionRegister::get_instance()->add_exception<AmbiguousPackageNameError>
+ ("AmbiguousPackageNameError", "PackageDatabaseLookupError");
+ ExceptionRegister::get_instance()->add_exception<NoSuchPackageError>
+ ("NoSuchPackageError", "PackageDatabaseLookupError");
+ ExceptionRegister::get_instance()->add_exception<NoSuchRepositoryError>
+ ("NoSuchRepositoryError", "PackageDatabaseLookupError");
enum_auto("QueryOrder", last_qo);
diff --git a/python/paludis_python.hh b/python/paludis_python.hh
index 88f50d2..1557278 100755
--- a/python/paludis_python.hh
+++ b/python/paludis_python.hh
@@ -20,9 +20,8 @@
#ifndef PALUDIS_GUARD_PYTHON_PALUDIS_PYTHON_HH
#define PALUDIS_GUARD_PYTHON_PALUDIS_PYTHON_HH 1
+#include <exception.hh>
#include <paludis/util/tr1_memory.hh>
-#include <paludis/util/tr1_functional.hh>
-
#include <paludis/util/stringify.hh>
#include <boost/python.hpp>
@@ -115,43 +114,6 @@ namespace paludis
return ! (a == b);
}
- // Translates Paludis C++ exception to a Python one with output of message() and backtrace() saved
- // in the corresponding string attributes of the Python exception.
- template <typename Ex_>
- class register_exception
- {
- private:
- PyObject * _e;
- const std::string _name;
- const std::string _longname;
-
- public:
- register_exception(const std::string & name) :
- _name(name),
- _longname("paludis."+name)
- {
- _e = PyErr_NewException(const_cast<char*>(_longname.c_str()), NULL, NULL);
- PyModule_AddObject(bp::detail::current_scope, const_cast<char*>(_name.c_str()), _e);
- bp::register_exception_translator<Ex_>(
- tr1::bind(tr1::mem_fn(&register_exception<Ex_>::translator),
- this, tr1::placeholders::_1)
- );
- }
-
- void
- translator(const Ex_ & x) const
- {
- PyObject * backtrace = PyString_FromString(x.backtrace("\n").c_str());
- PyObject * message = PyString_FromString(x.message().c_str());
- PyObject * what = PyString_FromString(x.what());
- PyObject_SetAttrString(_e, "backtrace", backtrace);
- PyObject_SetAttrString(_e, "message", message);
- PyObject_SetAttrString(_e, "what", what);
-
- PyErr_SetString(_e, x.message().c_str());
- }
- };
-
// expose Validated classes
template <typename V_, typename Data_=std::string>
class class_validated :
diff --git a/python/paludis_python_so.cc b/python/paludis_python_so.cc
index e3aa3a3..a037915 100644
--- a/python/paludis_python_so.cc
+++ b/python/paludis_python_so.cc
@@ -22,6 +22,7 @@
void expose_contents();
void expose_dep_spec();
void expose_environment();
+void expose_exception();
void expose_fs_entry();
void expose_log();
void expose_mask_reasons();
@@ -37,6 +38,7 @@ void expose_version_spec();
BOOST_PYTHON_MODULE(paludis)
{
+ expose_exception();
expose_version_spec();
expose_version_operator();
expose_version_requirements();
diff --git a/python/portage_dep_parser.cc b/python/portage_dep_parser.cc
index 82d67fd..e776b0f 100644
--- a/python/portage_dep_parser.cc
+++ b/python/portage_dep_parser.cc
@@ -27,10 +27,12 @@ namespace bp = boost::python;
void PALUDIS_VISIBLE expose_portage_dep_parser()
{
- static register_exception<DepStringParseError>
- DepStringParseError("DepStringParseError");
- static register_exception<DepStringNestingError>
- DepStringNestingError("DepStringNestingError");
+ ExceptionRegister::get_instance()->add_exception<DepStringError>
+ ("DepStringError", "BaseException");
+ ExceptionRegister::get_instance()->add_exception<DepStringParseError>
+ ("DepStringParseError", "DepStringError");
+ ExceptionRegister::get_instance()->add_exception<DepStringNestingError>
+ ("DepStringNestingError", "DepStringParseError");
bp::class_<PortageDepParser, boost::noncopyable>
pdp("PortageDepParser",
diff --git a/python/repository.cc b/python/repository.cc
index 8d848de..5e3e9d6 100644
--- a/python/repository.cc
+++ b/python/repository.cc
@@ -199,24 +199,23 @@ struct RepositoryPortageInterfaceWrapper :
void PALUDIS_VISIBLE expose_repository()
{
- static register_exception<PackageActionError>
- PackageActionError("PackageActionError");
- static register_exception<PackageInstallActionError>
- PackageInstallActionError("PackageInstallActionError");
- static register_exception<PackageFetchActionError>
- PackageFetchActionError("PackageFetchActionError");
- static register_exception<PackageUninstallActionError>
- PackageUninstallActionError("PackageUninstallActionError");
- static register_exception<PackageConfigActionError>
- PackageConfigActionError("PackageConfigActionError");
- static register_exception<EnvironmentVariableActionError>
- EnvironmentVariableActionError("EnvironmentVariableActionError");
+ ExceptionRegister::get_instance()->add_exception<PackageActionError>
+ ("PackageActionError", "BaseException");
+ ExceptionRegister::get_instance()->add_exception<PackageInstallActionError>
+ ("PackageInstallActionError", "PackageActionError");
+ ExceptionRegister::get_instance()->add_exception<PackageFetchActionError>
+ ("PackageFetchActionError", "PackageActionError");
+ ExceptionRegister::get_instance()->add_exception<PackageUninstallActionError>
+ ("PackageUninstallActionError", "PackageActionError");
+ ExceptionRegister::get_instance()->add_exception<PackageConfigActionError>
+ ("PackageConfigActionError", "PackageActionError");
+ ExceptionRegister::get_instance()->add_exception<EnvironmentVariableActionError>
+ ("EnvironmentVariableActionError", "PackageActionError");
class_collection<DestinationsCollection>
dc("DestinationsCollection",
"Iterable of Repository.\n"
"A set of Destinations."
-
);
bp::to_python_converter<std::pair<const std::string, std::string>,
diff --git a/python/version_operator.cc b/python/version_operator.cc
index ac25a73..8aa29db 100644
--- a/python/version_operator.cc
+++ b/python/version_operator.cc
@@ -34,8 +34,8 @@ vo_compare(const VersionOperator & self, const VersionSpec & v1, const VersionSp
void PALUDIS_VISIBLE expose_version_operator()
{
- static register_exception<BadVersionOperatorError>
- BadVersionOperatorError("BadVersionOperatorError");
+ ExceptionRegister::get_instance()->add_exception<BadVersionOperatorError>
+ ("BadVersionOperatorError", "BaseException");
enum_auto("VersionOperatorValue", last_vo);
diff --git a/python/version_spec.cc b/python/version_spec.cc
index 9cc943f..9d0eb3e 100644
--- a/python/version_spec.cc
+++ b/python/version_spec.cc
@@ -27,8 +27,8 @@ namespace bp = boost::python;
void PALUDIS_VISIBLE expose_version_spec()
{
- static register_exception<BadVersionSpecError>
- BadVersionSpecError("BadVersionSpecError");
+ ExceptionRegister::get_instance()->add_exception<BadVersionSpecError>
+ ("BadVersionSpecError", "BaseException");
bp::class_<VersionSpec>
vs("VersionSpec",