traceback over C API - still not working...

2007-10-20 Thread Sami Vaisanen
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

2007-10-19 Thread Sami Vaisanen
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

2007-10-18 Thread Sami Vaisanen
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

2007-10-18 Thread Sami Vaisanen
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

2007-10-16 Thread Sami Vaisanen
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