| 234 | } |
| 235 | |
| 236 | std::string PropertyPythonObject::toString() const |
| 237 | { |
| 238 | std::string repr; |
| 239 | Base::PyGILStateLocker lock; |
| 240 | try { |
| 241 | Py::Module pickle(PyImport_ImportModule("json"), true); |
| 242 | if (pickle.isNull()) { |
| 243 | throw Py::Exception(); |
| 244 | } |
| 245 | Py::Callable method(pickle.getAttr(std::string("dumps"))); |
| 246 | Py::Object dump; |
| 247 | if (this->object.hasAttr("dumps")) { |
| 248 | Py::Tuple args; |
| 249 | Py::Callable state(this->object.getAttr("dumps")); |
| 250 | dump = state.apply(args); |
| 251 | } |
| 252 | // support add-ons that use the old method names |
| 253 | else if (this->object.hasAttr("__getstate__") |
| 254 | #if PY_VERSION_HEX >= 0x030b0000 |
| 255 | && this->object.getAttr("__getstate__").hasAttr("__func__") |
| 256 | #endif |
| 257 | ) { |
| 258 | Py::Tuple args; |
| 259 | Py::Callable state(this->object.getAttr("__getstate__")); |
| 260 | dump = state.apply(args); |
| 261 | } |
| 262 | else if (this->object.hasAttr("__dict__")) { |
| 263 | dump = this->object.getAttr("__dict__"); |
| 264 | } |
| 265 | else { |
| 266 | dump = this->object; |
| 267 | } |
| 268 | |
| 269 | Py::Tuple args(1); |
| 270 | args.setItem(0, dump); |
| 271 | Py::Object res = method.apply(args); |
| 272 | Py::String str(res); |
| 273 | repr = str.as_std_string("ascii"); |
| 274 | } |
| 275 | catch (Py::Exception&) { |
| 276 | Py::String typestr(this->object.type().str()); |
| 277 | Base::Console().error("PropertyPythonObject::toString(): failed for %s\n", |
| 278 | typestr.as_string().c_str()); |
| 279 | Base::PyException e; // extract the Python error text |
| 280 | e.reportException(); |
| 281 | } |
| 282 | |
| 283 | return repr; |
| 284 | } |
| 285 | |
| 286 | void PropertyPythonObject::fromString(const std::string& repr) |
| 287 | { |
no test coverage detected