[C++-sig] Re: Calling a python function from C++ (from Jeff Holle)
Chad Austin
caustin at gmail.com
Thu Jul 1 05:00:19 CEST 2004
Straight from my codebase:
std::string getPythonErrorString() {
// Extra paranoia...
if (!PyErr_Occurred()) {
return "No Python error";
}
PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback);
PyErr_Clear();
std::string message = "Python error: ";
if (type) {
type = PyObject_Str(type);
message += PyString_AsString(type);
}
if (value) {
value = PyObject_Str(value);
message += ": ";
message += PyString_AsString(value);
}
Py_XDECREF(type);
Py_XDECREF(value);
Py_XDECREF(traceback);
return message;
}
void checkForPythonError() {
if (PyErr_Occurred()) {
throw PythonError(getPythonErrorString());
}
}
void requirePythonError() {
if (!PyErr_Occurred()) {
throw PythonError("Boost.Python exception, "
"but no Python error set.");
}
}
...
PYR_DEFINE_RUNTIME_ERROR(PythonError);
std::string getPythonErrorString();
void checkForPythonError();
void requirePythonError();
/**
* Allows us to check for Python errors at the end of a Python
* code block whether control left the end of the block or
* 'return' was used.
*/
struct PythonCodeErrorSentry {
~PythonCodeErrorSentry() {
if (!std::uncaught_exception()) {
checkForPythonError();
}
}
};
#define PYR_NO_UNUSED_WARNING(x) ((void)&(x))
#define PYR_BEGIN_PYTHON_CODE() \
try { \
PythonCodeErrorSentry sentry__; \
PYR_NO_UNUSED_WARNING(sentry__); // silly gcc
#define PYR_END_PYTHON_CODE() \
} \
catch (const boost::python::error_already_set&) { \
requirePythonError(); \
throw PythonError(getPythonErrorString()); \
}
May have bugs, but it should give you an idea of what to do. Notice I
don't do anything with the stacktrace object yet, but it wouldn't take
much more work.
HTH,
Chad
On Wed, 30 Jun 2004 02:39:46 -0400, Jeffrey Holle
<jeff.holle at verizon.net> wrote:
>
> Given what the name of this exception, I assume there is a source of
> information to obtain useful information about it.
> To this end, I've dug a bit into the Python C API and found the added
> the following to my code example:
>
> catch (error_already_set& x) {
> PyObject *err_type,*err_value,*err_traceback;
> PyErr_Fetch(&err_type,&err_value,&err_traceback);
> cout << "something bad happened" << endl;
> }
>
> While I see that err_type and error_value are not null pointers after
> the call to PyErr_Fetch, I don't know what to do with either to get at a
> useful message.
> Can anybody provide any hints?
>
>
>
> Jeffrey Holle wrote:
> > I've explored whats actually going on some with my debugger and now see
> > what is being thrown.
> > It is "error_already_set". This is a trivial object (it has no
> > attributes at all), and isn't much better than "catch (...)".
> > However, its name implies something. Is there a meaningful error
> > message set somewhere else that can be accessed within the catch clause
> > of "error_already_set"?
> >
> > Jeff Holle wrote:
> >
> >>>
> >>>
> >>>> An underlining concern I have is error handling. When
> >>>> PyImport_ImportModule fails, a NULL pointer is returned.
> >>>> Seems like the underlining machinery in "handle<>" is intolerant of
> >>>> this.
> >>>
> >>>
> >>>
> >>>
> >>>
> >>> What makes you say that?
> >>>
> >> You are correct about the success in compiling your much cleaner
> >> example, and it works :-) , but has a flaw.
> >>
> >> When I hide the needed python script, the call to
> >> PyImport_ImportModule returns NULL.
> >> When this occurres, both your example and what I had created, but
> >> commented out throws something because I can catch it with
> >> "catch(...)". I don't however know how to be more specific. Any
> >> hints? Whatever it is, it doesn't inherit from "exception".
> >>
> >> If I was operating on windows, I would anticipate it was a "structured
> >> exception", or whatever Microsoft calls their propritary stuff. Don't
> >> know of the equivalent on linux though. Without the "catch (...)",
> >> the command line program exits with "Aborted".
>
> _______________________________________________
> C++-sig mailing list
> C++-sig at python.org
> http://mail.python.org/mailman/listinfo/c++-sig
>
More information about the Cplusplus-sig
mailing list