From 9ae0940e99d9b30de562ac07ea16f6deb54545ea Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 29 Sep 2002 17:41:39 +0000 Subject: [PATCH] doc update [SVN r15551] --- doc/v2/errors.html | 174 ++++++++++++++++++++++++++++----------------- 1 file changed, 110 insertions(+), 64 deletions(-) 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.Python - <boost/python/errors.hpp> + + +
-

-

+

C++ Boost

+

Boost.Python

Header <boost/python/errors.hpp>

+

Contents

-
Introduction +
Introduction
-
Classes +
Classes
-
Class error_already_set +
Class + error_already_set
Class - error_already_set synopsis + error_already_set synopsis
+
+
-
Functions +
Functions
-
handle_exception +
handle_exception
-
expect_non_null -
throw_error_already_set +
expect_non_null
+ +
throw_error_already_set
+
-
Examples +
Examples

@@ -56,20 +71,24 @@

<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.

Classes

Class error_already_set

-

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 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.

-

Class error_already_set synopsis

+

Class error_already_set + synopsis

 namespace boost { namespace python
 {
@@ -86,84 +105,100 @@ void handle_exception() throw();
 
-
Requires: The first form requires that the expression 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).
Effects: The first form calls 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.
-
Postconditions: No exception is being handled +
Postconditions: No exception is being handled
-
Throws: nothing +
Throws: nothing
Rationale: At inter-language boundaries it is important to - 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(), 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);
 
-
Returns: x +
Returns: x
Throws: error_already_set() iff x == - 0. + "#error_already_set-spec">error_already_set() iff x == + 0.
-
Rationale: Simplifies error-handling when calling many - functions in the Python/C API, which - return 0 on error. +
Rationale: Simplifies error-handling when calling functions + in the Python/C + API which return 0 on error.
-
 void throw_error_already_set();
 
-
Effects: throw error_already_set(); + "#error_already_set-spec">error_already_set();
+
+ +
+
Rationale: Many platforms and compilers are not able to + consistently catch exceptions thrown across shared library boundaries. + Using this function from the Boost.Python library ensures that the + appropriate catch block in handle_exception() can catch the + exception.

Examples

 #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.

+ +