diff --git a/bazaar/BoostPyTest/main.cpp b/bazaar/BoostPyTest/main.cpp index 09fe140dc..670af2383 100644 --- a/bazaar/BoostPyTest/main.cpp +++ b/bazaar/BoostPyTest/main.cpp @@ -46,8 +46,19 @@ void BoostPyTest::EvalCB() { String s = ev.GetData(); - object o = eval(s.Begin(), main_namespace, main_namespace); - Value v = extract(o); + Value v; + try + { + object o = eval(s.Begin(), main_namespace, main_namespace); + v = extract(o); + } + catch(boost::python::error_already_set const &) + { + // Parse and output the exception + std::string perror_str = parse_py_exception(); + String es = perror_str; + v = ErrorValue(es); + } evr.SetData(v); } diff --git a/bazaar/CoreBoostPy/CoreBoostPy.cpp b/bazaar/CoreBoostPy/CoreBoostPy.cpp index 0792c5863..8e933bf2e 100644 --- a/bazaar/CoreBoostPy/CoreBoostPy.cpp +++ b/bazaar/CoreBoostPy/CoreBoostPy.cpp @@ -2,6 +2,26 @@ NAMESPACE_UPP +Value PyEvalConvert::Format(const Value& q) const +{ + Value v; + try + { + object arg(q); + locals["arg"] = arg; + object o = eval(expr.Begin(), locals, globals); + v = extract(o); + } + catch(boost::python::error_already_set const &) + { + // Parse and output the exception + std::string perror_str = parse_py_exception(); + String es = perror_str; + v = ErrorValue(es); + } + return v; +} + void export_Core() { ONCELOCK diff --git a/bazaar/CoreBoostPy/CoreBoostPy.h b/bazaar/CoreBoostPy/CoreBoostPy.h index 71f5f313d..f3e5300e7 100644 --- a/bazaar/CoreBoostPy/CoreBoostPy.h +++ b/bazaar/CoreBoostPy/CoreBoostPy.h @@ -16,14 +16,7 @@ public: mutable object locals; //added to by Format String expr; - virtual Value Format(const Value& q) const - { - object arg(q); - locals["arg"] = arg; - object o = eval(expr.Begin(), locals, globals); - Value v = extract(o); - return v; - } + virtual Value Format(const Value& q) const; }; void export_Core(); diff --git a/bazaar/CtrlLibBoostPy/CtrlLibBoostPy.upp b/bazaar/CtrlLibBoostPy/CtrlLibBoostPy.upp index ba1e42f05..c0575b448 100644 --- a/bazaar/CtrlLibBoostPy/CtrlLibBoostPy.upp +++ b/bazaar/CtrlLibBoostPy/CtrlLibBoostPy.upp @@ -1,7 +1,8 @@ uses CtrlLib, Py, - CoreBoostPy; + CoreBoostPy, + ValueCtrl; file Common.h, diff --git a/bazaar/CtrlLibBoostPy/init b/bazaar/CtrlLibBoostPy/init index aef294377..7829406e3 100644 --- a/bazaar/CtrlLibBoostPy/init +++ b/bazaar/CtrlLibBoostPy/init @@ -3,4 +3,5 @@ #include "CtrlLib/init" #include "Py/init" #include "CoreBoostPy/init" +#include "ValueCtrl/init" #endif diff --git a/bazaar/Py/Py.cpp b/bazaar/Py/Py.cpp index 95c08990b..32694c67c 100644 --- a/bazaar/Py/Py.cpp +++ b/bazaar/Py/Py.cpp @@ -5,5 +5,61 @@ using namespace boost::python; NAMESPACE_UPP +#ifdef flagBOOSTPY +// Parses the value of the active python exception +// NOTE SHOULD NOT BE CALLED IF NO EXCEPTION +std::string parse_py_exception() +{ + PyObject *type_ptr = NULL, *value_ptr = NULL, *traceback_ptr = NULL; + // Fetch the exception info from the Python C API + PyErr_Fetch(&type_ptr, &value_ptr, &traceback_ptr); + + // Fallback error + std::string ret("Unfetchable Python error"); + + // If the fetch got a type pointer, parse the type into the exception string + if(type_ptr != NULL){ + handle<> h_type(type_ptr); + str type_pstr(h_type); + // Extract the string from the boost::python object + extract e_type_pstr(type_pstr); + // If a valid string extraction is available, use it + // otherwise use fallback + if(e_type_pstr.check()) + ret = e_type_pstr(); + else + ret = "Unknown exception type"; + } + // Do the same for the exception value (the stringification of the exception) + if(value_ptr != NULL){ + handle<> h_val(value_ptr); + str a(h_val); + extract returned(a); + if(returned.check()) + ret += ": " + returned(); + else + ret += std::string(": Unparseable Python error: "); + } + // Parse lines from the traceback using the Python traceback module + if(traceback_ptr != NULL){ + handle<> h_tb(traceback_ptr); + // Load the traceback module and the format_tb function + object tb(import("traceback")); + object fmt_tb(tb.attr("format_tb")); + // Call format_tb to get a list of traceback strings + object tb_list(fmt_tb(h_tb)); + // Join the traceback strings into a single string + object tb_str(str("\n").join(tb_list)); + // Extract the string, check the extraction, and fallback in necessary + extract returned(tb_str); + if(returned.check()) + ret += ": " + returned(); + else + ret += std::string(": Unparseable Python traceback"); + } + return ret; +} +#endif + END_UPP_NAMESPACE diff --git a/bazaar/Py/Py.h b/bazaar/Py/Py.h index 60ef4d5ab..cc980fc67 100644 --- a/bazaar/Py/Py.h +++ b/bazaar/Py/Py.h @@ -19,4 +19,14 @@ #include +NAMESPACE_UPP + +#ifdef flagBOOSTPY +// Parses the value of the active python exception +// NOTE SHOULD NOT BE CALLED IF NO EXCEPTION +std::string parse_py_exception(); +#endif + +END_UPP_NAMESPACE + #endif diff --git a/bazaar/ValueAccessorEdit/ValueAccessorEdit.upp b/bazaar/ValueAccessorEdit/ValueAccessorEdit.upp index 325abfc5f..3060d38ff 100644 --- a/bazaar/ValueAccessorEdit/ValueAccessorEdit.upp +++ b/bazaar/ValueAccessorEdit/ValueAccessorEdit.upp @@ -9,6 +9,3 @@ file ValueAccessorEdit.cpp, ValueAccessorEdit.lay; -mainconfig - "" = "GUI SSE2"; - diff --git a/bazaar/ValueCtrl/ValueCtrl.cpp b/bazaar/ValueCtrl/ValueCtrl.cpp index 1d8cea353..620e56037 100644 --- a/bazaar/ValueCtrl/ValueCtrl.cpp +++ b/bazaar/ValueCtrl/ValueCtrl.cpp @@ -209,7 +209,7 @@ void ValueCtrl::OnAction() void ValueCtrl::Updated() { - if(v.IsNull()) + if(v.GetType() == VOID_V) SetText("#Nil#"); else SetText(v.ToString());