sbi
sbi

Reputation: 224129

How to extract a string from a Python 3 exception via the C API

I have some C++ code that runs Python 3 code using Boost.Python. If any exception in Python occurs, it is caught and a C++ exception thrown. I want to pass some minimal error information to the C++ exception.

What I currently have is this:

try {
    // execute python code via Boost.Python
} catch(boost::python::error_already_set&) {
    PyObject *ptype, *pvalue, *ptraceback;
    PyErr_Fetch(&ptype, &pvalue, &ptraceback);
    if(pvalue) {
        // ???
    }
}

There are many helpful answers here at SO, but they all seem to apply to Python 2, and their solutions do not work anymore. I have tried a few things like PyBytes_AsString, PyUnicode_AsUTF8, but all I get back are null pointers.

How do I go about extracting something meaningful from pvalue? For starters, the type name of the exception raised would already be quite helpful. If there was a string passed to the exception, getting that would be most helpful.

Upvotes: 0

Views: 1246

Answers (1)

sbi
sbi

Reputation: 224129

Of course, I found a solution myself immediately after I had formulated and posted this question.

This code finally does the trick and provides nice messages:

try {
    // execute python code via Boost.Python
} catch(boost::python::error_already_set&) {
    PyObject *ptype, *pvalue, *ptraceback;
    PyErr_Fetch(&ptype, &pvalue, &ptraceback);
    if(pvalue) {
        PyObject *pstr = PyObject_Str(pvalue);
        if(pstr) {
            const char* err_msg = PyUnicode_AsUTF8(pstr);
            if(pstr)
                // use err_msg
        }
        PyErr_Restore(ptype, pvalue, ptraceback);
    }
}

I'd be glad for any feedback, though. I know little of Python and less of its C API.

Upvotes: 4

Related Questions