how to get string printed by PyErr_Print( )?

G

grbgooglefan

PythonC API function PyErr_Print( ) prints an error string onto stderr
if PyErr_Occurred() is true.
I don't want to print this to stderr because my Python+C code is
running daemon mode & won't have terminal / stderr.
So, I want to retrieve the string which PyErr_Print( ) will print.
E.g., PyErr_Print() printed following string when I tried to call
setTuple with one extra argument
Traceback (most recent call last):
File "<string>", line 2, in isTacticSafe
IndexError: tuple assignment index out of range

How do I get this error message in a local char* & use it for further
error handling?

Also, is there any way to get an error number associated for these
error conditions using some getError function on the object returned
by PyErr_Occurred()?

Thanks.
 
R

Robert Kern

grbgooglefan said:
PythonC API function PyErr_Print( ) prints an error string onto stderr
if PyErr_Occurred() is true.
I don't want to print this to stderr because my Python+C code is
running daemon mode & won't have terminal / stderr.
So, I want to retrieve the string which PyErr_Print( ) will print.
E.g., PyErr_Print() printed following string when I tried to call
setTuple with one extra argument
Traceback (most recent call last):
File "<string>", line 2, in isTacticSafe
IndexError: tuple assignment index out of range

How do I get this error message in a local char* & use it for further
error handling?

Also, is there any way to get an error number associated for these
error conditions using some getError function on the object returned
by PyErr_Occurred()?

PyErr_Print() will import the sys module and try to use whatever file-like
object is sys.stderr. Replace this with a StringIO or an open file object just
like you would for output from the Python level.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 
C

Christian Heimes

grbgooglefan said:
PythonC API function PyErr_Print( ) prints an error string onto stderr
if PyErr_Occurred() is true.
I don't want to print this to stderr because my Python+C code is
running daemon mode & won't have terminal / stderr.
So, I want to retrieve the string which PyErr_Print( ) will print.
E.g., PyErr_Print() printed following string when I tried to call
setTuple with one extra argument
Traceback (most recent call last):
File "<string>", line 2, in isTacticSafe
IndexError: tuple assignment index out of range

I suggest a different approach. A daemon must have a stdin, stdout and
stderr connected to a terminal. You can use freopen() to redirect stderr
and stdout to a log file and fclose() to close stdin.

http://www.gnu.org/software/libc/manual/html_mono/libc.html#Opening-Streams

Christian
 
G

grbgooglefan

I suggest a different approach. A daemon must have a stdin, stdout and
stderr connected to a terminal. You can use freopen() to redirect stderr
and stdout to a log file and fclose() to close stdin.

http://www.gnu.org/software/libc/manual/html_mono/libc.html#Opening-S...

Christian

I do not want to redirect anything to file. Because I do not want to
avoid the disk access completely - for reading as well as writing.
I liked the 1st option suggested by Robert Kern.

Can you please explain a little bit how can I replace sys.stderr with
StringIO or my char* buffer?
I have to show the error message of Python code compilation &
execution to the user on the GUI & therefore I want to capture the
error message directly instead of logging it to file.

Thanks in advance for all your help.
 
G

grbgooglefan

I do not want to redirect anything to file. Because I do not want to
avoid the disk access completely - for reading as well as writing.
I liked the 1st option suggested by Robert Kern.

Can you please explain a little bit how can I replace sys.stderr with
StringIO or my char* buffer?
I have to show the error message of Python code compilation &
execution to the user on the GUI & therefore I want to capture the
error message directly instead of logging it to file.

Thanks in advance for all your help.- Hide quoted text -

- Show quoted text -

Well, I managed to do it myself. Here is what I am doing now to do
this. In Python-C/C++ world, if someone wants to do the same thing,
may use this.
Note: For this, am assigning the cStringIO object to sys.stderr once I
do Py_Initialize & then use cStringIO.getvalue() everytime I get
error.
While importing cStringIO module with Python-2.3.3, I faced the
problem of "undefined symbol:pyObject_SelfIter". I could resolve that
also. I have put that note in the post which I had opened for that.
/+++++++++++++++++++++++++++++++++++++++++++++++
PyObject *_pPyModule;
PyObject *_pPyDictionary;
PyObject *_pPyGetValFunc;
PyObject *_pPyobStringIO;

Init(){
// Py_Initialize should have been done by now.....
PyObject *modStringIO = NULL;
PyObject *obFuncStringIO = NULL;

// Import cStringIO module
modStringIO = PyImport_ImportModule("cStringIO");
if(PyErr_Occurred() || modStringIO == NULL){
printf("pyParserEvaluator::Init::pyImport cStringIO failed:");
PyErr_Print();
goto PY_INIT_ERR;
}
// get StringIO constructor
obFuncStringIO = PyObject_GetAttrString(modStringIO, "StringIO");
if(PyErr_Occurred() || obFuncStringIO == NULL){
printf("pyParserEvaluator::Init: cant find cStringIO.StringIO:");
PyErr_Print();
goto PY_INIT_ERR;
}
// Construct cStringIO object
_pPyobStringIO = PyObject_CallObject(obFuncStringIO, NULL);
if(PyErr_Occurred() || _pPyobStringIO==NULL){
printf("pyParserEvaluator::Init: cStringIO.StringIO() failed:");
PyErr_Print();
goto PY_INIT_ERR;
}
// get getvalue() method in StringIO instance
_pPyGetValFunc = PyObject_GetAttrString(_pPyobStringIO,
"getvalue");
if(PyErr_Occurred() || _pPyGetValFunc==NULL){
printf("pyParserEvaluator::Init: cant find getvalue function:");
PyErr_Print();
goto PY_INIT_ERR;
}
// try assigning this object to sys.stderr
ret = PySys_SetObject("stderr", _pPyobStringIO);
if(ret != 0){
printf("failed to assign _pPyobStringIO to stderr\n");
goto PY_INIT_ERR;
}
return ret;

PY_INIT_ERR:
Py_XDECREF(modStringIO);
Py_XDECREF(obFuncStringIO);
Py_XDECREF(_pPyobStringIO);
Py_XDECREF(_pPyGetValFunc);
}

int _getPythonErrorMessage()
{
// call getvalue() method in StringIO instance
int ret = 0;
PyObject *obResult=NULL;
char *sresult = NULL;
obResult = PyObject_CallObject(_pPyGetValFunc, NULL);
if(PyErr_Occurred() || obResult==NULL){
printf("getvalue() failed\n");
ret = -1;
goto CLEAN_AND_RETURN;
}
// did getvalue return a string?
if(!PyString_Check(obResult)){
printf("getvalue() did not return error string\n");
ret = -1;
goto CLEAN_AND_RETURN;
}
// retrieve error message string from this object
if(NULL != (sresult = PyString_AsString(obResult))){
pErrorString = strdup(sresult);
} else {
ret = -1;
goto CLEAN_AND_RETURN;
}
return(ret);

CLEAN_AND_RETURN:
Py_XDECREF(obResult);
return(ret);
}
=================================================
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top