Skip to content

Commit

Permalink
Remove ExtensionProxy and rely on default Python proxy for extensions.
Browse files Browse the repository at this point in the history
…fixes #4534
  • Loading branch information
ickby authored and wwmayer committed Jan 30, 2021
1 parent 37952a5 commit 446ce21
Show file tree
Hide file tree
Showing 13 changed files with 32 additions and 54 deletions.
6 changes: 1 addition & 5 deletions src/App/Extension.h
Expand Up @@ -336,13 +336,9 @@ class ExtensionPythonT : public ExtensionT
ExtensionPythonT() {
ExtensionT::m_isPythonExtension = true;
ExtensionT::initExtensionType(ExtensionPythonT::getExtensionClassTypeId());

EXTENSION_ADD_PROPERTY(ExtensionProxy,(Py::Object()));
}
virtual ~ExtensionPythonT() {
}

PropertyPythonObject ExtensionProxy;
};

typedef ExtensionPythonT<App::Extension> ExtensionPython;
Expand All @@ -352,7 +348,7 @@ typedef ExtensionPythonT<App::Extension> ExtensionPython;
Base::PyGILStateLocker lock;\
Py::Object result;\
try {\
Property* proxy = this->extensionGetPropertyByName("ExtensionProxy");\
Property* proxy = this->getExtendedContainer()->getPropertyByName("Proxy");\
if (proxy && proxy->getTypeId() == PropertyPythonObject::getClassTypeId()) {\
Py::Object feature = static_cast<PropertyPythonObject*>(proxy)->getValue();\
if (feature.hasAttr(std::string("function"))) {\
Expand Down
3 changes: 1 addition & 2 deletions src/App/ExtensionContainerPy.xml
Expand Up @@ -17,8 +17,7 @@
</Documentation>
<Methode Name="addExtension">
<Documentation>
<UserDocu>Adds an extension to the object. Requires the string identifier as well as the python object
used to check for overridden functions (most likely self)</UserDocu>
<UserDocu>Adds an extension to the object. Requires the string identifier for the python extension as argument</UserDocu>
</Documentation>
</Methode>
<Methode Name="hasExtension" Const="true">
Expand Down
14 changes: 2 additions & 12 deletions src/App/ExtensionContainerPyImp.cpp
Expand Up @@ -198,8 +198,7 @@ PyObject* ExtensionContainerPy::hasExtension(PyObject *args) {
PyObject* ExtensionContainerPy::addExtension(PyObject *args) {

char *typeId;
PyObject* proxy;
if (!PyArg_ParseTuple(args, "sO", &typeId, &proxy))
if (!PyArg_ParseTuple(args, "s", &typeId))
return NULL;

//get the extension type asked for
Expand All @@ -223,16 +222,7 @@ PyObject* ExtensionContainerPy::addExtension(PyObject *args) {
GetApplication().signalBeforeAddingDynamicExtension(*getExtensionContainerPtr(), typeId);
ext->initExtension(getExtensionContainerPtr());

//set the proxy to allow python overrides
App::Property* pp = ext->extensionGetPropertyByName("ExtensionProxy");
if (!pp) {
std::stringstream str;
str << "Accessing the proxy property failed!" << std::ends;
throw Py::Exception(Base::BaseExceptionFreeCADError,str.str());
}
static_cast<PropertyPythonObject*>(pp)->setPyObject(proxy);

// The PyTypeObject is shared by all instances of this type and therefore
// The PyTypeObject is shared by all instances of this type and therefore
// we have to add new methods only once.
PyObject* obj = ext->getExtensionPyObject();
PyMethodDef* meth = reinterpret_cast<PyMethodDef*>(obj->ob_type->tp_methods);
Expand Down
4 changes: 0 additions & 4 deletions src/Gui/ViewProviderExtension.h
Expand Up @@ -130,13 +130,9 @@ class ViewProviderExtensionPythonT : public ExtensionT
ViewProviderExtensionPythonT() {
ExtensionT::m_isPythonExtension = true;
ExtensionT::initExtensionType(ViewProviderExtensionPythonT::getExtensionClassTypeId());

EXTENSION_ADD_PROPERTY(ExtensionProxy,(Py::Object()));
}
virtual ~ViewProviderExtensionPythonT() {
}

App::PropertyPythonObject ExtensionProxy;
};

typedef ViewProviderExtensionPythonT<Gui::ViewProviderExtension> ViewProviderExtensionPython;
Expand Down
8 changes: 4 additions & 4 deletions src/Mod/Arch/ArchBuildingPart.py
Expand Up @@ -323,8 +323,8 @@ class BuildingPart(ArchIFC.IfcProduct):
def __init__(self,obj):

obj.Proxy = self
obj.addExtension('App::GroupExtensionPython', self)
#obj.addExtension('App::OriginGroupExtensionPython', self)
obj.addExtension('App::GroupExtensionPython')
#obj.addExtension('App::OriginGroupExtensionPython')
self.setProperties(obj)

def setProperties(self,obj):
Expand Down Expand Up @@ -488,8 +488,8 @@ class ViewProviderBuildingPart:

def __init__(self,vobj):

vobj.addExtension("Gui::ViewProviderGroupExtensionPython", self)
#vobj.addExtension("Gui::ViewProviderGeoFeatureGroupExtensionPython", self)
vobj.addExtension("Gui::ViewProviderGroupExtensionPython")
#vobj.addExtension("Gui::ViewProviderGeoFeatureGroupExtensionPython")
vobj.Proxy = self
self.setProperties(vobj)
vobj.ShapeColor = ArchCommands.getDefaultColor("Helpers")
Expand Down
4 changes: 2 additions & 2 deletions src/Mod/Arch/ArchProject.py
Expand Up @@ -158,7 +158,7 @@ def setProperties(self, obj):
ArchIFC.IfcContext.setProperties(self, obj)
pl = obj.PropertiesList
if not hasattr(obj,"Group"):
obj.addExtension("App::GroupExtensionPython", self)
obj.addExtension("App::GroupExtensionPython")
self.Type = "Project"

def onDocumentRestored(self, obj):
Expand All @@ -185,7 +185,7 @@ class _ViewProviderProject(ArchIFCView.IfcContextView):

def __init__(self,vobj):
vobj.Proxy = self
vobj.addExtension("Gui::ViewProviderGroupExtensionPython", self)
vobj.addExtension("Gui::ViewProviderGroupExtensionPython")

def getIcon(self):
"""Return the path to the appropriate icon.
Expand Down
4 changes: 2 additions & 2 deletions src/Mod/Arch/ArchSite.py
Expand Up @@ -631,7 +631,7 @@ def setProperties(self,obj):
if not "OriginOffset" in pl:
obj.addProperty("App::PropertyVector","OriginOffset","Site",QT_TRANSLATE_NOOP("App::Property","An optional offset between the model (0,0,0) origin and the point indicated by the geocoordinates"))
if not hasattr(obj,"Group"):
obj.addExtension("App::GroupExtensionPython", self)
obj.addExtension("App::GroupExtensionPython")
if not "IfcType" in pl:
obj.addProperty("App::PropertyEnumeration","IfcType","IFC",QT_TRANSLATE_NOOP("App::Property","The type of this object"))
obj.IfcType = ArchIFC.IfcTypes
Expand Down Expand Up @@ -819,7 +819,7 @@ class _ViewProviderSite:

def __init__(self,vobj):
vobj.Proxy = self
vobj.addExtension("Gui::ViewProviderGroupExtensionPython", self)
vobj.addExtension("Gui::ViewProviderGroupExtensionPython")
self.setProperties(vobj)

def setProperties(self,vobj):
Expand Down
2 changes: 1 addition & 1 deletion src/Mod/Draft/draftmake/make_clone.py
Expand Up @@ -108,7 +108,7 @@ def make_clone(obj, delta=None, forcedraft=False):
# fall back to Draft clone mode
if not cl:
cl = App.ActiveDocument.addObject("Part::FeaturePython","Clone")
cl.addExtension("Part::AttachExtensionPython", None)
cl.addExtension("Part::AttachExtensionPython")
cl.Label = prefix + obj[0].Label
Clone(cl)
if App.GuiUp:
Expand Down
2 changes: 1 addition & 1 deletion src/Mod/Draft/draftobjects/draftlink.py
Expand Up @@ -79,7 +79,7 @@ def __setstate__(self, state):
def attach(self, obj):
"""Set up the properties when the object is attached."""
if self.use_link:
obj.addExtension('App::LinkExtensionPython', None)
obj.addExtension('App::LinkExtensionPython')
self.linkSetup(obj)

def canLinkProperties(self, _obj):
Expand Down
4 changes: 2 additions & 2 deletions src/Mod/Fem/femsolver/solverbase.py
Expand Up @@ -48,7 +48,7 @@ class Proxy(object):

def __init__(self, obj):
obj.Proxy = self
obj.addExtension("App::GroupExtensionPython", self)
obj.addExtension("App::GroupExtensionPython")

def createMachine(self, obj, directory, testmode):
raise NotImplementedError()
Expand Down Expand Up @@ -78,7 +78,7 @@ class ViewProxy(object):

def __init__(self, vobj):
vobj.Proxy = self
vobj.addExtension("Gui::ViewProviderGroupExtensionPython", self)
vobj.addExtension("Gui::ViewProviderGroupExtensionPython")

def setEdit(self, vobj, mode=0):
try:
Expand Down
2 changes: 1 addition & 1 deletion src/Mod/Part/BasicShapes/Shapes.py
Expand Up @@ -43,7 +43,7 @@ def __init__(self, obj):
obj.addProperty("App::PropertyLength","OuterRadius","Tube","Outer radius").OuterRadius = 5.0
obj.addProperty("App::PropertyLength","InnerRadius","Tube","Inner radius").InnerRadius = 2.0
obj.addProperty("App::PropertyLength","Height","Tube", "Height of the tube").Height = 10.0
obj.addExtension("Part::AttachExtensionPython", self)
obj.addExtension("Part::AttachExtensionPython")

def execute(self, fp):
if fp.InnerRadius >= fp.OuterRadius:
Expand Down
2 changes: 1 addition & 1 deletion src/Mod/Part/BasicShapes/ViewProviderShapes.py
Expand Up @@ -36,7 +36,7 @@ class ViewProviderTube:
def __init__(self, obj):
''' Set this object to the proxy object of the actual view provider '''
obj.Proxy = self
obj.addExtension("PartGui::ViewProviderAttachExtensionPython", self)
obj.addExtension("PartGui::ViewProviderAttachExtensionPython")
obj.setIgnoreOverlayIcon(True, "PartGui::ViewProviderAttachExtensionPython")

def attach(self, obj):
Expand Down
31 changes: 14 additions & 17 deletions src/Mod/Test/Document.py
Expand Up @@ -171,7 +171,7 @@ def testObjects(self):
FreeCAD.Console.PrintLog(" exception thrown, OK\n")
else:
self.fail("no exception thrown")
self.failUnless(sorted(L1.getEnumerationsOfProperty('Enum')) == sorted(['Zero', 'One', 'Two', 'Three', 'Four']))
self.failUnless(sorted(L1.getEnumerationsOfProperty('Enum')) == sorted(['Zero', 'One', 'Two', 'Three', 'Four']))

#self.failUnless(L1.IntegerList == [4711] )
#f = L1.FloatList
Expand Down Expand Up @@ -245,7 +245,7 @@ def testExtensions(self):
#we should have all methods we need to handle extensions
try:
self.failUnless(not grp.hasExtension("App::GroupExtensionPython"))
grp.addExtension("App::GroupExtensionPython", self)
grp.addExtension("App::GroupExtensionPython")
self.failUnless(grp.hasExtension("App::GroupExtension"))
self.failUnless(grp.hasExtension("App::GroupExtensionPython"))
grp.addObject(obj)
Expand All @@ -260,8 +260,9 @@ def allowObject(self, obj):
return False;

callback = SpecialGroup()
grp2 = self.Doc.addObject("App::DocumentObject", "Extension_3")
grp2.addExtension("App::GroupExtensionPython", callback)
grp2 = self.Doc.addObject("App::FeaturePython", "Extension_3")
grp2.addExtension("App::GroupExtensionPython")
grp2.Proxy = callback

try:
self.failUnless(grp2.hasExtension("App::GroupExtension"))
Expand All @@ -281,7 +282,7 @@ def testExtensionBug0002785(self):

class MyExtension():
def __init__(self, obj):
obj.addExtension("App::GroupExtensionPython", self)
obj.addExtension("App::GroupExtensionPython")

obj = self.Doc.addObject("App::DocumentObject", "myObj")
MyExtension(obj)
Expand All @@ -293,19 +294,19 @@ def __init__(self, obj):
def testExtensionGroup(self):
obj = self.Doc.addObject("App::DocumentObject", "Obj")
grp = self.Doc.addObject("App::FeaturePython", "Extension_2")
grp.addExtension("App::GroupExtensionPython", None)
grp.addExtension("App::GroupExtensionPython")
grp.Group = [obj]
self.assertTrue(obj in grp.Group)

def testExtensionBugViewProvider(self):

class Layer():
def __init__(self, obj):
obj.addExtension("App::GroupExtensionPython", self)
obj.addExtension("App::GroupExtensionPython")

class LayerViewProvider():
def __init__(self, obj):
obj.addExtension("Gui::ViewProviderGroupExtensionPython", self)
obj.addExtension("Gui::ViewProviderGroupExtensionPython")
obj.Proxy = self

obj = self.Doc.addObject("App::FeaturePython","Layer")
Expand Down Expand Up @@ -385,7 +386,7 @@ def tearDown(self):
# class must be defined in global scope to allow it to be reloaded on document open
class SaveRestoreSpecialGroup():
def __init__(self, obj):
obj.addExtension("App::GroupExtensionPython", self)
obj.addExtension("App::GroupExtensionPython")
obj.Proxy = self

def allowObject(self, obj):
Expand All @@ -394,7 +395,7 @@ def allowObject(self, obj):
# class must be defined in global scope to allow it to be reloaded on document open
class SaveRestoreSpecialGroupViewProvider():
def __init__(self, obj):
obj.addExtension("Gui::ViewProviderGroupExtensionPython", self)
obj.addExtension("Gui::ViewProviderGroupExtensionPython")
obj.Proxy = self

def testFunction(self):
Expand Down Expand Up @@ -468,7 +469,7 @@ def testExtensionSaveRestore(self):
grp1 = Doc.addObject("App::DocumentObject", "Extension_1")
grp2 = Doc.addObject("App::FeaturePython", "Extension_2")

grp1.addExtension("App::GroupExtensionPython", None)
grp1.addExtension("App::GroupExtensionPython")
SaveRestoreSpecialGroup(grp2)
if FreeCAD.GuiUp:
SaveRestoreSpecialGroupViewProvider(grp2.ViewObject)
Expand All @@ -480,16 +481,12 @@ def testExtensionSaveRestore(self):

self.failUnless(Doc.Extension_1.hasExtension("App::GroupExtension"))
self.failUnless(Doc.Extension_2.hasExtension("App::GroupExtension"))
self.failUnless(Doc.Extension_1.ExtensionProxy is None)
self.failUnless(Doc.Extension_2.ExtensionProxy is not None)
self.failUnless(Doc.Extension_2.Group[0] is Doc.Obj)
self.failUnless(hasattr(Doc.Extension_2.Proxy, 'allowObject'))
self.failUnless(hasattr(Doc.Extension_2.ExtensionProxy, 'allowObject'))

if FreeCAD.GuiUp:
self.failUnless(Doc.Extension_2.ViewObject.hasExtension("Gui::ViewProviderGroupExtensionPython"))
self.failUnless(hasattr(Doc.Extension_2.ViewObject.Proxy, 'testFunction'))
self.failUnless(hasattr(Doc.Extension_2.ViewObject.ExtensionProxy, 'testFunction'))

FreeCAD.closeDocument("SaveRestoreExtensions")

Expand Down Expand Up @@ -1803,7 +1800,7 @@ def testObject(self):
self.failUnless(self.Obs.parameter2.pop() == 'Prop')
self.failUnless(not self.Obs.signal and not self.Obs.parameter and not self.Obs.parameter2)

pyobj.addExtension("App::GroupExtensionPython", None)
pyobj.addExtension("App::GroupExtensionPython")
self.failUnless(self.Obs.signal.pop() == 'ObjDynExt')
self.failUnless(self.Obs.parameter.pop() is pyobj)
self.failUnless(self.Obs.parameter2.pop() == 'App::GroupExtensionPython')
Expand Down Expand Up @@ -1945,7 +1942,7 @@ def testGuiObserver(self):
self.failUnless(self.GuiObs.parameter.pop(0) is obj.ViewObject)
self.failUnless(not self.GuiObs.signal and not self.GuiObs.parameter and not self.GuiObs.parameter2)

obj.ViewObject.addExtension("Gui::ViewProviderGroupExtensionPython", None)
obj.ViewObject.addExtension("Gui::ViewProviderGroupExtensionPython")
self.failUnless(self.Obs.signal.pop() == 'ObjDynExt')
self.failUnless(self.Obs.parameter.pop() is obj.ViewObject)
self.failUnless(self.Obs.parameter2.pop() == 'Gui::ViewProviderGroupExtensionPython')
Expand Down

0 comments on commit 446ce21

Please sign in to comment.