@@ -43,6 +43,14 @@ namespace moveit {
4343namespace python {
4444namespace {
4545
46+ /* * In order to assign new property values in Python, we need to convert the Python object
47+ * to a boost::any instance of the correct type. As the C++ type cannot be inferred from
48+ * the Python type, we can support this assignment only for a few basic types (see fromPython())
49+ * as well as ROS message types. For other types, a generic assignment via
50+ * stage.properties["property"] = value
51+ * is not possible. Instead, use the .property<Type> declaration on the stage to allow for
52+ * direct assignment like this: stage.property = value
53+ **/
4654class PropertyConverterRegistry
4755{
4856 struct Entry
@@ -102,10 +110,8 @@ py::object PropertyConverterRegistry::toPython(const boost::any& value) {
102110
103111 auto it = REGISTRY_SINGLETON.types_ .find (value.type ());
104112 if (it == REGISTRY_SINGLETON.types_ .end ()) {
105- std::string msg (" No Python -> C++ conversion for: " );
106- msg += boost::core::demangle (value.type ().name ());
107- PyErr_SetString (PyExc_TypeError, msg.c_str ());
108- throw py::error_already_set ();
113+ std::string name = boost::core::demangle (value.type ().name ());
114+ throw py::type_error (" No Python -> C++ conversion for: " + name);
109115 }
110116
111117 return it->second .to_ (value);
@@ -115,12 +121,9 @@ std::string rosMsgName(PyObject* object) {
115121 py::object o = py::reinterpret_borrow<py::object>(object);
116122 try {
117123 return o.attr (" _type" ).cast <std::string>();
118- } catch (const py::error_already_set&) {
119- // change error to TypeError
120- std::string msg = o.attr (" __class__" ).attr (" __name__" ).cast <std::string>();
121- msg += " is not a ROS message type" ;
122- PyErr_SetString (PyExc_TypeError, msg.c_str ());
123- throw py::error_already_set ();
124+ } catch (const py::error_already_set& e) {
125+ // object is not a ROS message type, return it's class name instead
126+ return o.attr (" __class__" ).attr (" __name__" ).cast <std::string>();
124127 }
125128}
126129
@@ -138,12 +141,8 @@ boost::any PropertyConverterRegistry::fromPython(const py::object& po) {
138141
139142 const std::string& ros_msg_name = rosMsgName (o);
140143 auto it = REGISTRY_SINGLETON.msg_names_ .find (ros_msg_name);
141- if (it == REGISTRY_SINGLETON.msg_names_ .end ()) {
142- std::string msg (" No Python -> C++ conversion for: " );
143- msg += ros_msg_name;
144- PyErr_SetString (PyExc_TypeError, msg.c_str ());
145- throw py::error_already_set ();
146- }
144+ if (it == REGISTRY_SINGLETON.msg_names_ .end ())
145+ throw py::type_error (" No C++ conversion available for (property) type: " + ros_msg_name);
147146
148147 return it->second ->second .from_ (po);
149148}
0 commit comments