diff --git a/doc/v2/errors.html b/doc/v2/errors.html index 6e364e8f..a87c308d 100644 --- a/doc/v2/errors.html +++ b/doc/v2/errors.html @@ -1,53 +1,68 @@ - + + +
+|
- |
Boost.PythonHeader <boost/python/errors.hpp>+ |
+
error_already_set
+ error_already_seterror_already_set synopsis
+ error_already_set synopsis<boost/python/errors.hpp> provides types and
functions for managing and translating between Python and C++ exceptions.
This is relatively low-level functionality that is mostly used internally
- by Boost.Python. Users should seldom need it.
+ by Boost.Python. Users should seldom need it.
error_already_seterror_already_set is an exception type which can be thrown
- to indicate that a Python error has occurred. If thrown, the precondition
- is that error_already_set is an exception type which can be
+ thrown to indicate that a Python error has occurred. If thrown, the
+ precondition is that PyErr_Occurred()
- returns a value convertible to true.
+ returns a value convertible to true. Portable code shouldn't
+ throw this exception type directly, but should instead use throw_error_already_set(),
+ below.
namespace boost { namespace python
{
@@ -86,84 +105,100 @@ void handle_exception() throw();
Requires: The first form requires that the expression
+ function0<void>(f)
is valid. The second form requires that a C++ exception is currently
- being handled (see section 15.1 in the C++ standard).
+ being handled (see section 15.1 in the C++ standard).f() inside a
- try block whose catch clauses set an
- appropriate Python exception for the C++ exception caught, returning
- true if an exception was caught, false
- otherwise. The second form passes a function which rethrows the exception
- currently being handled to the first form.
+ try block which first attempts to use all registered exception translators. If none of
+ those translates the exception, the catch clauses then set
+ an appropriate Python exception for the C++ exception caught, returning
+ true if an exception was thrown, false
+ otherwise. The second form passes a function which rethrows the
+ exception currently being handled to the first form.handle_exception to manage exception translation whenever
- your C++ code is called directly from the Python API. This is done for
- you automatically by the usual function wrapping facilities: make_function(), make_constructor(), module::def and class_::def). The second form can be more
- convenient to use (see the example below), but
- various compilers have problems when exceptions are rethrown from within
- an enclosing try block.
+ ensure that no C++ exceptions escape, since the calling language
+ usually doesn't have the equipment neccessary to properly unwind the
+ stack. Use handle_exception to manage exception
+ translation whenever your C++ code is called directly from the Python
+ API. This is done for you automatically by the usual function wrapping
+ facilities: make_function(),
+ make_constructor(),
+ def() and class_::def(). The second form can be
+ more convenient to use (see the example below),
+ but various compilers have problems when exceptions are rethrown from
+ within an enclosing try block.-template <class T> T* expect_non_null(T* x); +template <class T> T* expect_non_null(T* x);
x
+ xerror_already_set() iff x ==
- 0.
+ "#error_already_set-spec">error_already_set() iff x ==
+ 0.void throw_error_already_set();
throw error_already_set();
+ "#error_already_set-spec">error_already_set();catch block in handle_exception() can catch the
+ exception.
#include <string>
#include <boost/python/errors.hpp>
-#include <boost/python/reference.hpp>
+#include <boost/python/object.hpp>
+#include <boost/python/handle.hpp>
// Returns a std::string which has the same value as obj's "__name__"
// attribute.
-std::string get_name(boost::python::ref obj)
+std::string get_name(boost::python::object obj)
{
// throws if there's no __name__ attribute
PyObject* p = boost::python::expect_non_null(
- PyObject_GetAttrString(obj.get(), "__name__"));
+ PyObject_GetAttrString(obj.ptr(), "__name__"));
+
+ char const* s = PyString_AsString(p);
+ if (s != 0)
+ Py_DECREF(p);
// throws if it's not a Python string
std::string result(
boost::python::expect_non_null(
PyString_AsString(p)));
- Py_XDECREF(p); // Done with p
+ Py_DECREF(p); // Done with p
return result;
}
@@ -172,12 +207,19 @@ std::string get_name(boost::python::ref obj)
// Demonstrate form 1 of handle_exception
//
-// Place a Python Int object whose value is 1 if a and b have
+// Place into result a Python Int object whose value is 1 if a and b have
// identical "__name__" attributes, 0 otherwise.
-void same_name_impl(PyObject*& result, PyObject* a, PyObject* b)
+void same_name_impl(PyObject*& result, boost::python::object a, boost::python::object b)
{
result = PyInt_FromLong(
- get_name(boost::python::ref(a1)) == get_name(boost::python::ref(a2)));
+ get_name(a) == get_name(a2));
+}
+
+object borrowed_object(PyObject* p)
+{
+ return boost::python::object(
+ boost::python::handle<>(
+ boost::python::borrowed(a1)));
}
// This is an example Python 'C' API interface function
@@ -194,7 +236,7 @@ same_name(PyObject* args, PyObject* keywords)
// Use boost::bind to make an object compatible with
// boost::Function0<void>
if (boost::python::handle_exception(
- boost::bind<void>(same_name_impl, boost::ref(result), a1, a2)))
+ boost::bind<void>(same_name_impl, boost::ref(result), borrowed_object(a1), borrowed_object(a2))))
{
// an exception was thrown; the Python error was set by
// handle_exception()
@@ -217,9 +259,10 @@ same_name2(PyObject* args, PyObject* keywords)
if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &a1, &a2))
return 0;
+
try {
return PyInt_FromLong(
- get_name(boost::python::ref(a1)) == get_name(boost::python::ref(a2)));
+ get_name(borrowed_object(a1)) == get_name(borrowed_object(a2)));
}
catch(...)
{
@@ -232,10 +275,13 @@ same_name2(PyObject* args, PyObject* keywords)
Revised
- 17 November, 2002
+ 29 September, 2002
+
-
- © Copyright Dave
- Abrahams 2002. All Rights Reserved.
+
© Copyright Dave Abrahams 2002. All Rights
+ Reserved.
+
+