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; ilen; ++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 -- http://mail.python.org/mailman/listinfo/python-list
traceback over C API and PyObject_CallObject
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. 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. Thanks 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; } -- http://mail.python.org/mailman/listinfo/python-list
Re: Getting error message/trace over the C API
On Tue, 16 Oct 2007 18:55:22 +, Duncan Booth wrote: Sami Vaisanen [EMAIL PROTECTED] wrote: Hello group, I'm writing a C++ based application that embeds the python engine. Now I have a problem regarding exception/error information. Is there a way to get the exception message and possibly the traceback into a string for example? I've been eyeballing the PyErr_ module and it seems fairly limited. In other words PyErr_Print() calls the right functions for getting the exception information but unfortunately it is hardwired to print this data directly into sys.stderr, and for an embedded application this is completely inappropriate. Please advice how to do this. All you have to do is call whatever functions you would call from Python. e.g. from C you need to import traceback, then call getattr to get the appropriate function (e.g. format_exc or format_exception), then just call it. 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; } str evaluates to None, any ideas what gives here? I've also tried to call the traceback with a different function, such as PyObject_CallFunctionObjArgs but the result is still same. Thanks -- http://mail.python.org/mailman/listinfo/python-list
Re: Extending Python with C API
On Thu, 13 Sep 2007 21:26:33 -0400, Carsten Haese wrote: On Thu, 2007-09-13 at 18:05 -0700, Thierry Masson wrote: Hello, I'm trying to use the C API to extend Python. I've looked at various books and web sites (including the docs at python.org) and I can't get any of the samples to work. Below is a very minimalist example that I'm trying to get working and I was wondering if someone could tell me where I'm going wrong. It's probably something very obvious to those familiar with this technique. [snip...] The setup script builds the library OK, and I've verified that gtestmodule.so is getting created. But when I try to run a test script ( test.py, above) that uses the library, I get this error: Traceback (most recent call last): File test.py, line 2, in ? import gtestmodule ImportError: ./gtestmodule.so: undefined symbol: PyBuildValue Your module C code uses an unknown function by the name of PyBuildValue. The actual name of the function you mean is Py_BuildValue. HTH, 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; } str evaluates to None, any ideas what gives here? I've also tried to call the traceback with a different function, such as PyObject_CallFunctionObjArgs but the result is still same. Thanks -- http://mail.python.org/mailman/listinfo/python-list
Getting error message/trace over the C API
Hello group, I'm writing a C++ based application that embeds the python engine. Now I have a problem regarding exception/error information. Is there a way to get the exception message and possibly the traceback into a string for example? I've been eyeballing the PyErr_ module and it seems fairly limited. In other words PyErr_Print() calls the right functions for getting the exception information but unfortunately it is hardwired to print this data directly into sys.stderr, and for an embedded application this is completely inappropriate. I have seen solutions that propose writing a custom Python class with write method and using that to grab the output from sys.stderr and then saving the data for example into a variable for later access, but unless Im mistaken this solution (not only that it is extremely ugly) is not thread safe. Even if a thread in my application is holding GIL, the lock can be released by extensions/the interpreter and thus opens up a race condition regarding that grabber object. Please advice how to do this. -sami -- http://mail.python.org/mailman/listinfo/python-list