471,337 Members | 829 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,337 software developers and data experts.

traceback over C API - still not working...

This is becoming utterly painful process.... I found out that the return
value from "format_exception" function is NOT a list, i.e. PyList_Check()
fails. PySequence_Check() succeeds but then PySequence_List() gives me
back -1. So wtf?

I must say the API is crap on this part. Im trying to get error
information regarding previous error and if all i get back is another
error indicator, then what am I supposed to do? Recursive error handling?
Sounds like da bomb!

The API should have two levels of error handling. First level should
expose a conventional error code mechanism for checking for bad params
etc. Only if the error code says that there was a python error during
evaluation/compilation should one need to use this mechanism.

Just my two cents.

Thanks for help.

void get_python_error_info(string& info)
{
GIL g;

PyObject* type = NULL;
PyObject* value = NULL;
PyObject* trace = NULL;
PyErr_Fetch(&type, &value, &trace);

py_ref ref_type(type);
py_ref ref_value(value);
py_ref ref_trace(trace);

py_ref name(PyString_FromString("traceback"));
py_ref module(PyImport_Import(name.get()));
if (!module)
{
PyErr_Clear();
return;
}
PyObject* list = NULL;
if (trace)
{
py_ref fun(PyObject_GetAttrString(module.get(), "format_exception"));
if (fun)
list = PyObject_CallFunctionObjArgs(type, value, trace, NULL);
PyErr_Clear();
}
else
{
py_ref fun(PyObject_GetAttrString(module.get(), "format_exception_only"));
if (fun)
list = PyObject_CallFunctionObjArgs(type, value, NULL);
PyErr_Clear();
}
if (list && PySequence_Check(list))
{
Py_ssize_t len = PySequence_Size(list);

for (Py_ssize_t i=0; i<len; ++i)
{
// bla bla
}
}
Py_XDECREF(list);
PyErr_Clear();
}


Hello group,

I'm trying to get the Python exception information (message and
traceback)
stored into a string in my C++ code. However all i get back is the string
"None".
This is what you get (actually "None\n") when there is no error set.
All the checks pass and all pointers get a value from the python
API calls. I've also tried with a different function such as
PyObject_CallFunctionObjArgs but the result is the same.
Since you already know the three components (type, value, trace), I'd use
traceback.format_exception instead (and remove the PyErr_Restore call -
I'm unsure if it works the way you expect it).
In this case you have to pass three arguments, so yes, use
PyObject_CallFunctionObjArgs (remember the final NULL). Beware:
format_exception returns a formatted list, not a string. You have to
concatenate all the elements (either using ''.join or repeteadly calling
PyString_Concat)
void get_python_exception(string& message, string& traceback)
{
GIL g;
PyObject* type = NULL;
PyObject* value = NULL;
PyObject* trace = NULL;
PyErr_Fetch(&type, &value, &trace);
py_ref ref_type(type);
py_ref ref_value(value);
py_ref ref_trace(trace);
py_ref name(PyString_FromString("traceback"));
py_ref module(PyImport_Import(name.get()));
if (module)
{
py_ref fun(PyObject_GetAttrString(module.get(), "format_exc"));
if (fun)
{
PyErr_Restore(type, value, trace);
ref_type.release();
ref_value.release();
ref_trace.release();
py_ref ret(PyObject_CallObject(fun.get(), NULL));
if (ret && PyString_Check(ret.get()))
{
char* str = PyString_AsString(ret.get());
message = str;
traceback = "traceback not available";
return;
}
}
}
message = "message not available";
traceback = "traceback not available";
}

--
Gabriel Genellina

Oct 20 '07 #1
1 1881
En Sat, 20 Oct 2007 14:47:52 -0300, Sami Vaisanen <en********@hotmail.com>
escribi�:
This is becoming utterly painful process.... I found out that the return
value from "format_exception" function is NOT a list, i.e. PyList_Check()
fails. PySequence_Check() succeeds but then PySequence_List() gives me
back -1. So wtf?
It seems very unlikely, since the traceback module is written in Python.
It clearly returns a list.
py_ref fun(PyObject_GetAttrString(module.get(),
"format_exception"));
if (fun)
list = PyObject_CallFunctionObjArgs(type, value, trace,
NULL);
Of course, you get a list if you actually call the function...

--
Gabriel Genellina

Oct 20 '07 #2

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Oliver Walczak | last post: by
5 posts views Thread by Thomas Guettler | last post: by
7 posts views Thread by Robin Becker | last post: by
1 post views Thread by Josh Close | last post: by
reply views Thread by Echo | last post: by
1 post views Thread by metaperl.etc | last post: by
5 posts views Thread by Bob Greschke | last post: by
8 posts views Thread by gregpinero | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.