diff --git a/src/Base/PyObjectBase.cpp b/src/Base/PyObjectBase.cpp index dd55b4369e..8ae349253a 100644 --- a/src/Base/PyObjectBase.cpp +++ b/src/Base/PyObjectBase.cpp @@ -181,6 +181,17 @@ int PyObjectBase::__setattr(PyObject *obj, char *attr, PyObject *value) return -1; } + // If an attribute references this as parent then reset it + // before setting the new attribute + PyObject* cur = static_cast(obj)->_getattr(attr); + if (cur) { + if (PyObject_TypeCheck(cur, &(PyObjectBase::Type))) { + PyObjectBase* base = static_cast(cur); + base->resetAttribute(); + } + Py_DECREF(cur); + } + int ret = static_cast(obj)->_setattr(attr, value); #if 1 if (ret == 0) { @@ -265,6 +276,18 @@ PyObject *PyObjectBase::_repr(void) return Py_BuildValue("s", a.str().c_str()); } +void PyObjectBase::resetAttribute() +{ + if (this->attribute) { + free(this->attribute); + this->attribute = 0; + } + if (this->parent) { + Py_DECREF(this->parent); + this->parent = 0; + } +} + void PyObjectBase::setAttributeOf(const char* attr, const PyObjectBase* par) { if (this->parent != par) { diff --git a/src/Base/PyObjectBase.h b/src/Base/PyObjectBase.h index a1fcd50f42..62642e2c7c 100644 --- a/src/Base/PyObjectBase.h +++ b/src/Base/PyObjectBase.h @@ -196,6 +196,7 @@ class BaseExport PyObjectBase : public PyObject protected: /// destructor virtual ~PyObjectBase(); + void resetAttribute(); public: /** Constructor diff --git a/src/Mod/Test/Document.py b/src/Mod/Test/Document.py index ae15e84ec7..b850ccfef6 100644 --- a/src/Mod/Test/Document.py +++ b/src/Mod/Test/Document.py @@ -342,6 +342,18 @@ class DocumentBasicCases(unittest.TestCase): self.Doc.removeObject(L7.Name) self.Doc.removeObject(L8.Name) + def testPropertyLink(self): + o1 = self.Doc.addObject("App::FeatureTest","test1") + o2 = self.Doc.addObject("App::FeatureTest","test2") + o3 = self.Doc.addObject("App::FeatureTest","test3") + + o1.Link=o2 + self.assertEqual(o1.Link, o2) + o1.Link=o3 + self.assertEqual(o1.Link, o3) + o2.Placement = FreeCAD.Placement() + self.assertEqual(o1.Link, o3) + def tearDown(self): #closing doc FreeCAD.closeDocument("CreateTest")