Remove ExtensionProxy and rely on default Python proxy for extensions. fixes #0004534

This commit is contained in:
Stefan Tröger
2021-01-17 10:45:50 +01:00
committed by wwmayer
parent 37952a5949
commit 446ce21517
13 changed files with 32 additions and 54 deletions

View File

@@ -336,13 +336,9 @@ public:
ExtensionPythonT() {
ExtensionT::m_isPythonExtension = true;
ExtensionT::initExtensionType(ExtensionPythonT::getExtensionClassTypeId());
EXTENSION_ADD_PROPERTY(ExtensionProxy,(Py::Object()));
}
virtual ~ExtensionPythonT() {
}
PropertyPythonObject ExtensionProxy;
};
typedef ExtensionPythonT<App::Extension> ExtensionPython;
@@ -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"))) {\

View File

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

View File

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

View File

@@ -130,13 +130,9 @@ public:
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;

View File

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

View File

@@ -158,7 +158,7 @@ class _Project(ArchIFC.IfcContext):
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):
@@ -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.

View File

@@ -631,7 +631,7 @@ class _Site(ArchIFC.IfcProduct):
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
@@ -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):

View File

@@ -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:

View File

@@ -79,7 +79,7 @@ class DraftLink(DraftObject):
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):

View File

@@ -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()
@@ -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:

View File

@@ -43,7 +43,7 @@ class TubeFeature:
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:

View File

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

View File

@@ -171,7 +171,7 @@ class DocumentBasicCases(unittest.TestCase):
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
@@ -245,7 +245,7 @@ class DocumentBasicCases(unittest.TestCase):
#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)
@@ -260,8 +260,9 @@ class DocumentBasicCases(unittest.TestCase):
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"))
@@ -281,7 +282,7 @@ class DocumentBasicCases(unittest.TestCase):
class MyExtension():
def __init__(self, obj):
obj.addExtension("App::GroupExtensionPython", self)
obj.addExtension("App::GroupExtensionPython")
obj = self.Doc.addObject("App::DocumentObject", "myObj")
MyExtension(obj)
@@ -293,7 +294,7 @@ class DocumentBasicCases(unittest.TestCase):
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)
@@ -301,11 +302,11 @@ class DocumentBasicCases(unittest.TestCase):
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")
@@ -385,7 +386,7 @@ class DocumentBasicCases(unittest.TestCase):
# 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):
@@ -394,7 +395,7 @@ class SaveRestoreSpecialGroup():
# 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):
@@ -468,7 +469,7 @@ class DocumentSaveRestoreCases(unittest.TestCase):
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)
@@ -480,16 +481,12 @@ class DocumentSaveRestoreCases(unittest.TestCase):
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")
@@ -1803,7 +1800,7 @@ class DocumentObserverCases(unittest.TestCase):
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')
@@ -1945,7 +1942,7 @@ class DocumentObserverCases(unittest.TestCase):
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')