Commit 4b477bb5 authored by Utkarsh Ayachit's avatar Utkarsh Ayachit

vtkPythonAlgorithm: cleanup exception reporting code.

vtkPythonAlgorithm's exception reporting code has issues with Python 3
where it could segfault. Cleaning it up to simply use `PyErr_Print`.
We typically already capture stdout/stderr to pipe to VTK's error
reporting mechanism hence nothing special needs to be done.
parent b248b5ba
......@@ -104,102 +104,17 @@ static PyObject* VTKToPython(vtkObjectBase* obj)
return vtkPythonUtil::GetObjectFromPointer(obj);
}
static std::string GetPythonErrorString()
{
vtkPythonScopeGilEnsurer gilEnsurer;
PyObject* type;
PyObject* value;
PyObject* traceback;
// Increments refcounts for returns.
PyErr_Fetch(&type, &value, &traceback);
// Put the returns in smartpointers that will
// automatically decrement refcounts
vtkSmartPyObject sType(type);
vtkSmartPyObject sValue(value);
vtkSmartPyObject sTraceback(traceback);
if (!sType)
{
return "No error from Python?!";
}
std::string exc_string;
vtkSmartPyObject tbModule(PyImport_ImportModule("traceback"));
if (tbModule)
{
vtkSmartPyObject formatFunction(PyObject_GetAttrString(tbModule.GetPointer(), "format_exception"));
vtkSmartPyObject args(PyTuple_New(3));
Py_INCREF(sType.GetPointer()); // PyTuple steals a reference.
PyTuple_SET_ITEM(args.GetPointer(), 0, sType.GetPointer());
Py_INCREF(sValue.GetPointer()); // PyTuple steals a reference.
PyTuple_SET_ITEM(args.GetPointer(), 1, sValue.GetPointer());
Py_INCREF(sTraceback.GetPointer()); // PyTuple steals a reference.
PyTuple_SET_ITEM(args.GetPointer(), 2, sTraceback.GetPointer());
vtkSmartPyObject formatList(PyObject_Call(formatFunction.GetPointer(), args, nullptr));
vtkSmartPyObject fastFormatList(PySequence_Fast(formatList.GetPointer(), "format_exception didn't return a list..."));
Py_ssize_t sz = PySequence_Size(formatList.GetPointer());
PyObject** lst = PySequence_Fast_ITEMS(fastFormatList.GetPointer());
exc_string = "\n";
for (Py_ssize_t i = 0; i < sz; ++i)
{
PyObject* str = lst[i];
#ifndef VTK_PY3K
exc_string += PyString_AsString(str);
#else
PyObject *bytes = PyUnicode_EncodeLocale(str, VTK_PYUNICODE_ENC);
if (bytes)
{
exc_string += PyBytes_AsString(bytes);
Py_DECREF(bytes);
}
#endif
}
}
else
{
vtkSmartPyObject pyexc_string(PyObject_Str(sValue));
if (pyexc_string)
{
#ifndef VTK_PY3K
exc_string = PyString_AsString(pyexc_string);
#else
PyObject *bytes = PyUnicode_EncodeLocale(
pyexc_string, VTK_PYUNICODE_ENC);
if (bytes)
{
exc_string = PyBytes_AsString(bytes);
Py_DECREF(bytes);
}
#endif
}
else
{
exc_string = "<Unable to convert Python error to string>";
}
}
PyErr_Clear();
return exc_string;
}
int vtkPythonAlgorithm::CheckResult(const char* method, const vtkSmartPyObject &res)
{
vtkPythonScopeGilEnsurer gilEnsurer;
if (!res)
{
std::string pymsg = GetPythonErrorString();
vtkErrorMacro("Failure when calling method: \""
<< method << "\": " << pymsg << ".");
vtkErrorMacro("Failure when calling method: \"" << method << "\":");
if (PyErr_Occurred() != nullptr)
{
PyErr_Print();
PyErr_Clear();
}
return 0;
}
if (!PyInt_Check(res))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment