issue #0002902: PyObjectBase notification chain can lead to unexpected changes to document

This commit is contained in:
wmayer
2017-02-14 00:32:30 +01:00
parent 89925e21a3
commit b72aa9f369
3 changed files with 36 additions and 0 deletions

View File

@@ -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<PyObjectBase*>(obj)->_getattr(attr);
if (cur) {
if (PyObject_TypeCheck(cur, &(PyObjectBase::Type))) {
PyObjectBase* base = static_cast<PyObjectBase*>(cur);
base->resetAttribute();
}
Py_DECREF(cur);
}
int ret = static_cast<PyObjectBase*>(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) {

View File

@@ -196,6 +196,7 @@ class BaseExport PyObjectBase : public PyObject
protected:
/// destructor
virtual ~PyObjectBase();
void resetAttribute();
public:
/** Constructor

View File

@@ -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")