Skip to content

Commit

Permalink
issue #2902: PyObjectBase notification chain can lead to unexpected c…
Browse files Browse the repository at this point in the history
…hanges to document
  • Loading branch information
wwmayer committed Feb 13, 2017
1 parent 89925e2 commit b72aa9f
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/Base/PyObjectBase.cpp
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions src/Base/PyObjectBase.h
Expand Up @@ -196,6 +196,7 @@ class BaseExport PyObjectBase : public PyObject
protected:
/// destructor
virtual ~PyObjectBase();
void resetAttribute();

public:
/** Constructor
Expand Down
12 changes: 12 additions & 0 deletions src/Mod/Test/Document.py
Expand Up @@ -342,6 +342,18 @@ def testRecompute(self):
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")
Expand Down

0 comments on commit b72aa9f

Please sign in to comment.