how to set sys.stderr to object of cStringIO type
grbgooglefan
ganeshborse at gmail.com
Tue Jan 15 06:01:49 EST 2008
On Jan 15, 5:45 pm, grbgooglefan <ganeshbo... at gmail.com> wrote:
> I am in a perculiar situation. I want to use PyRun_SimpleString for
> creating Python functions in embedded Python in C++.
> But there could be cases when Python function code compilation could
> fail & PyRun_SimpleString will return -1 as return status. At this
> time, it prints the error message to sys.stderr.
> So, we do not have any control or cannot use that message to show to
> user to correct the errors in the function code.
> I could assign an object of cStringIO type to sys.stderr at Python
> command prompt as below:
>
> >>> import sys
> >>> import cStringIO
> >>> obj=cStringIO.StringIO()
> >>> sys.stderr=obj
>
> And then using the obj.getvalue(), I could print exceptions printed to
> sys.stderr.
>
> But, I am not able to figure out, how can I do this same thing in
> Python/C API in my program using Py* functions?
>
> How do we set the "sys.stderr" to cStringIO object from Python
> embedded in C++ or C?
>
> Should I be using PyFile_FromFile for convert the cStringIO object?
> Please help.
I have got a solution for this. Would like to know if this is the
correct way or will it cause any problems if program runs for long
time?
/***************************************************/
/--1st stage is assign object of cStringIO to sys.stderr at
initialization
/-- once that is done, we can call getvalue() on that object on every
error.
/-----------------------------------------------------/
PyObject *_pPyobStringIO;
PyObject *_pPyGetValFunc;
_pPyobStringIO=NULL;
_pPyGetValFunc=NULL;
PyObject *obFuncStringIO = NULL;
int ret1 = 0;
// Import cStringIO module
PyObject * 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 the getvalue function ptr
_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
ret1 = PySys_SetObject("stderr", _pPyobStringIO);
if(ret1 != 0){
printf("failed to assign _pPyobStringIO to stderr\n");
} else
printf("assigned _pPyobStringIO to stderr\n");
PY_INIT_ERR:
printf("pyParseEvaluator::pyParseEvaluator failed\n");
/
**********************************************************************/
int ret = PyRun_SimpleString(strFunction);
if(ret != 0){
// call getvalue() method in StringIO instance
PyObject *obResult=NULL;
obResult = PyObject_CallObject(_pPyGetValFunc, NULL);
if(PyErr_Occurred() || obResult==NULL){
printf("getvalue() failed\n");
return -1;
} else printf("PyObject_CallObject on getvalue is ok\n");
// did getvalue return a string?
if(!PyString_Check(obResult)){
printf("getvalue() did not return error string\n");
return -1;
} else printf("getvalue returned string object\n");
// retrieve error message string from this object
char *sresult = NULL;
if(NULL != (sresult = PyString_AsString(obResult))){
printf("result string was [%s]\n",sresult);
}
}
/**********************************************************/
More information about the Python-list
mailing list