Formatting Traceback info in the Python/C API

NG ngopalas at yahoo.com
Wed Mar 5 03:34:35 CET 2003


> To the contrary, it's the most straightforward way of doing it:  reuse code
> that already does what you want.  You probably want PyObject_CallMethod(),
> though, which works for module.attribute calls as well as object.method
> calls.  If you want to reproduce all the logic in C instead, you deserve all
> the pain you're experiencing <wink>.

You were right, it was definitely easier to do this by doing a
PyImportImport("traceback") and the PyModuleGetDict ... attached is
the code in case anyone reads this in the future. I know I have
benefited from the newsgroup articles immensely.

void formatPythonError(const CString& cstr)
{

 	PyObject *pName, *pModule, *pDict, *pFunc;
	PyObject *pArgs, *pValue;
	PyObject *err = PyErr_Occurred();
	char tb_string[1024];
	CString err_str ;
	if(err)
	{
         	PyObject *temp, *exc_typ, *exc_val, *exc_tb;
		err_str = qstr;


		PyErr_Fetch(&exc_typ,&exc_val,&exc_tb);
		PyErr_NormalizeException(&exc_typ,&exc_val,&exc_tb);

		pName = PyString_FromString("traceback");
		pModule = PyImport_Import(pName);
		Py_DECREF(pName);

		temp = PyObject_Str(exc_typ);
		if (temp != NULL)
		{
                 	err_str += PyString_AsString(temp);
			err_str += "\n";
		}
                temp = PyObject_Str(exc_val);
		if (temp != NULL){
			err_str += PyString_AsString(temp);
		}
                Py_DECREF(temp);
		err_str += "\n";

		if (exc_tb != NULL && pModule != NULL )
		{
                 	pDict = PyModule_GetDict(pModule);
			pFunc = PyDict_GetItemString(pDict, "format_tb");
			if (pFunc && PyCallable_Check(pFunc))
			{
                         	pArgs = PyTuple_New(1);
                         	pArgs = PyTuple_New(1);
				PyTuple_SetItem(pArgs, 0, exc_tb);
				pValue = PyObject_CallObject(pFunc, pArgs);
				if (pValue != NULL)
				{
                                 	int len = PyList_Size(pValue);
                                        if (len > 0) {
                                                PyObject *t,*tt;
                                                int i;
                                                char *buffer;
                                                for (i = 0; i < len;
i++) {
                                                        tt =
PyList_GetItem(pValue,i);
                                                        t =
Py_BuildValue("(O)",tt);
                                                        if
(!PyArg_ParseTuple(t,"s",&buffer)){
                                                               
return;
                                                        }
                                                       
strcpy(tb_string,buffer);
                                                        err_str +=
tb_string;
                                                        err_str +=
"\n";
                                                }
                                        }
				}
                                Py_DECREF(pValue);
				Py_DECREF(pArgs);
			}
		}
                Py_DECREF(pModule);

		GUIDisplay("Error"+err_str);
		PyErr_Restore(exc_typ, exc_val, exc_tb);
		PyErr_Print();
		return;
	}
}




More information about the Python-list mailing list