#define CV_HAS_CONVERSION_ERROR(x) (((x) == -1) && PyErr_Occurred())
+static PyObject* opencv_error = NULL;
class ArgInfo
{
//static inline PyObject* from(const T& src);
};
+// exception-safe pyopencv_to
+template<typename _Tp> static
+bool pyopencv_to_safe(PyObject* obj, _Tp& value, const ArgInfo& info)
+{
+ try
+ {
+ return pyopencv_to(obj, value, info);
+ }
+ catch (const std::exception &e)
+ {
+ PyErr_SetString(opencv_error, cv::format("Conversion error: %s, what: %s", info.name, e.what()).c_str());
+ return false;
+ }
+ catch (...)
+ {
+ PyErr_SetString(opencv_error, cv::format("Conversion error: %s", info.name).c_str());
+ return false;
+ }
+}
+
template<typename T> static
bool pyopencv_to(PyObject* obj, T& p, const ArgInfo& info) { return PyOpenCV_Converter<T>::to(obj, p, info); }
template<typename T> static
PyObject* pyopencv_from(const T& src) { return PyOpenCV_Converter<T>::from(src); }
-static PyObject* opencv_error = NULL;
-
static bool isPythonBindingsDebugEnabled()
{
static bool param_debug = cv::utils::getConfigurationParameterBool("OPENCV_PYTHON_DEBUG", false);
{ \
PyErr_SetString(opencv_error, e.what()); \
return 0; \
+} \
+catch (...) \
+{ \
+ PyErr_SetString(opencv_error, "Unknown C++ exception from OpenCV code"); \
+ return 0; \
}
using namespace cv;
gen_template_mappable = Template("""
{
${mappable} _src;
- if (pyopencv_to(src, _src, info))
+ if (pyopencv_to_safe(src, _src, info))
{
return cv_mappable_to(_src, dst);
}
if( PyMapping_HasKeyString(src, (char*)"$propname") )
{
tmp = PyMapping_GetItemString(src, (char*)"$propname");
- ok = tmp && pyopencv_to(tmp, dst.$propname, ArgInfo("$propname", false));
+ ok = tmp && pyopencv_to_safe(tmp, dst.$propname, ArgInfo("$propname", false));
Py_DECREF(tmp);
if(!ok) return false;
}""")
PyErr_SetString(PyExc_TypeError, "Cannot delete the ${member} attribute");
return -1;
}
- return pyopencv_to(value, p->v${access}${member}, ArgInfo("value", false)) ? 0 : -1;
+ return pyopencv_to_safe(value, p->v${access}${member}, ArgInfo("value", false)) ? 0 : -1;
}
""")
failmsgp("Incorrect type of object (must be '${name}' or its derivative)");
return -1;
}
- return pyopencv_to(value, _self_${access}${member}, ArgInfo("value", false)) ? 0 : -1;
+ return pyopencv_to_safe(value, _self_${access}${member}, ArgInfo("value", false)) ? 0 : -1;
}
""")
code = "static bool pyopencv_to(PyObject* src, %s& dst, const ArgInfo& info)\n{\n PyObject* tmp;\n bool ok;\n" % (self.cname)
code += "".join([gen_template_set_prop_from_map.substitute(propname=p.name,proptype=p.tp) for p in self.props])
if self.base:
- code += "\n return pyopencv_to(src, (%s&)dst, info);\n}\n" % all_classes[self.base].cname
+ code += "\n return pyopencv_to_safe(src, (%s&)dst, info);\n}\n" % all_classes[self.base].cname
else:
code += "\n return true;\n}\n"
return code
if a.tp == 'char':
code_cvt_list.append("convert_to_char(pyobj_%s, &%s, %s)" % (a.name, a.name, a.crepr()))
else:
- code_cvt_list.append("pyopencv_to(pyobj_%s, %s, %s)" % (a.name, a.name, a.crepr()))
+ code_cvt_list.append("pyopencv_to_safe(pyobj_%s, %s, %s)" % (a.name, a.name, a.crepr()))
all_cargs.append([arg_type_info, parse_name])