how to get string printed by PyErr_Print( )?

grbgooglefan ganeshborse at gmail.com
Thu Jan 31 05:41:42 EST 2008


On Jan 9, 8:01 pm, grbgooglefan <ganeshbo... at gmail.com> wrote:
> On Dec 19 2007, 5:55 pm, Christian Heimes <li... at cheimes.de> wrote:
> >grbgooglefanwrote:
> > > PythonC API functionPyErr_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 whichPyErr_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-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.- 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);
}
=================================================



More information about the Python-list mailing list