Commit 720136bf by Wenzel Jakob

RAII wrapper for error state

parent 1f2e417d
......@@ -111,18 +111,16 @@ PYBIND11_NOINLINE inline std::string error_string() {
return "Unknown internal error occurred";
}
PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback);
error_scope scope; // Preserve error state
std::string errorString;
if (type) {
errorString += handle(type).attr("__name__").cast<std::string>();
if (scope.type) {
errorString += handle(scope.type).attr("__name__").cast<std::string>();
errorString += ": ";
}
if (value)
errorString += (std::string) handle(value).str();
if (scope.value)
errorString += (std::string) handle(scope.value).str();
PyErr_Restore(type, value, traceback);
return errorString;
}
......
......@@ -420,6 +420,13 @@ template <typename T> struct format_descriptor<T, typename std::enable_if<std::i
template <typename T> constexpr const char format_descriptor<
T, typename std::enable_if<std::is_integral<T>::value>::type>::value[2];
/// RAII wrapper that temporarily clears any Python error state
struct error_scope {
PyObject *type, *value, *trace;
error_scope() { PyErr_Fetch(&type, &value, &trace); }
~error_scope() { PyErr_Restore(type, value, trace); }
};
PYBIND11_DECL_FMT(float, "f");
PYBIND11_DECL_FMT(double, "d");
PYBIND11_DECL_FMT(bool, "?");
......
......@@ -1309,6 +1309,7 @@ NAMESPACE_END(detail)
template <return_value_policy policy = return_value_policy::automatic_reference, typename... Args>
void print(Args &&...args) {
error_scope scope; // Preserve error state
auto c = detail::collect_arguments<policy>(std::forward<Args>(args)...);
detail::print(c.args(), c.kwargs());
}
......
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