From 9add3ba199c01f5f6ff4eae60557c4b22b625940 Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Wed, 9 Dec 2020 19:28:19 +0100 Subject: [PATCH] Sketcher/Part: Python handling of GeometryExtensions without a Python counterpart ================================================================================= Some geometry extensions do not provide a PyObject as they do not have a Python counterpart as it would serve no purpose to have it. This commit handles this situation making sure to provide the right error to Python or to ignore the extension where appropriate. --- src/Mod/Part/App/GeometryPyImp.cpp | 23 +++++++++++++++---- src/Mod/Sketcher/App/ExternalGeometryFacade.h | 4 ++++ .../App/ExternalGeometryFacadePyImp.cpp | 22 ++++++++++++++---- src/Mod/Sketcher/App/GeometryFacadePyImp.cpp | 22 ++++++++++++++---- 4 files changed, 59 insertions(+), 12 deletions(-) diff --git a/src/Mod/Part/App/GeometryPyImp.cpp b/src/Mod/Part/App/GeometryPyImp.cpp index 7d89f9a13b..4f0fffe730 100644 --- a/src/Mod/Part/App/GeometryPyImp.cpp +++ b/src/Mod/Part/App/GeometryPyImp.cpp @@ -261,6 +261,10 @@ PyObject* GeometryPy::getExtensionOfType(PyObject *args) PyErr_SetString(PartExceptionOCCError, "Geometry extension does not exist anymore."); return 0; } + catch(Base::NotImplementedError) { + PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not implement a Python counterpart."); + return 0; + } } else { @@ -296,6 +300,10 @@ PyObject* GeometryPy::getExtensionOfName(PyObject *args) PyErr_SetString(PartExceptionOCCError, "Geometry extension does not exist anymore."); return 0; } + catch(Base::NotImplementedError) { + PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not implement a Python counterpart."); + return 0; + } } @@ -408,7 +416,7 @@ PyObject* GeometryPy::getExtensions(PyObject *args) try { const std::vector> ext = this->getGeometryPtr()->getExtensions(); - PyObject* list = PyList_New(ext.size()); + PyObject* list = PyList_New(0); for (std::size_t i=0; i(p->getPyObject())->copy(tuple.ptr()); - PyList_SetItem( list, i, cpy); + try { + Py::Tuple tuple; + PyObject* cpy = static_cast(p->getPyObject())->copy(tuple.ptr()); + + PyList_Append( list, cpy); + Py_DECREF(cpy); + } + catch(Base::NotImplementedError) { + // silently ignoring extensions not having a Python object + } } } diff --git a/src/Mod/Sketcher/App/ExternalGeometryFacade.h b/src/Mod/Sketcher/App/ExternalGeometryFacade.h index eed4591e8f..788ffbcb0b 100644 --- a/src/Mod/Sketcher/App/ExternalGeometryFacade.h +++ b/src/Mod/Sketcher/App/ExternalGeometryFacade.h @@ -41,6 +41,10 @@ class ExternalGeometryFacadePy; // // Exactly the same considerations as for GeometryFacade apply (see documentation of GeometryFacade). // +// It was not made publicly deriving from GeometryFacade because it is not possible to differentiate functions by return type, which is the +// case of getFacade() returning a unique_ptr to GeometryFacade in GeometryFacade, and one to ExternalGeometryFacade. I have not managed to +// find a good solution to this problem, thus the code duplication. +// // Summary Remarks: // It is intended to have a separate type (not being a Geometry type). // it is intended to have the relevant interface in full for the sketcher extension only diff --git a/src/Mod/Sketcher/App/ExternalGeometryFacadePyImp.cpp b/src/Mod/Sketcher/App/ExternalGeometryFacadePyImp.cpp index 50b29dcdb7..57bc771906 100644 --- a/src/Mod/Sketcher/App/ExternalGeometryFacadePyImp.cpp +++ b/src/Mod/Sketcher/App/ExternalGeometryFacadePyImp.cpp @@ -318,6 +318,10 @@ PyObject* ExternalGeometryFacadePy::getExtensionOfType(PyObject *args) PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not exist anymore."); return 0; } + catch(Base::NotImplementedError) { + PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not implement a Python counterpart."); + return 0; + } } else { @@ -353,6 +357,10 @@ PyObject* ExternalGeometryFacadePy::getExtensionOfName(PyObject *args) PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not exist anymore."); return 0; } + catch(Base::NotImplementedError) { + PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not implement a Python counterpart."); + return 0; + } } @@ -465,7 +473,7 @@ PyObject* ExternalGeometryFacadePy::getExtensions(PyObject *args) try { const std::vector> ext = this->getExternalGeometryFacadePtr()->getExtensions(); - PyObject* list = PyList_New(ext.size()); + PyObject* list = PyList_New(0); for (std::size_t i=0; i(std::const_pointer_cast(p)->getPyObject())->copy(tuple.ptr()); + try { + Py::Tuple tuple; + PyObject* cpy = static_cast(std::const_pointer_cast(p)->getPyObject())->copy(tuple.ptr()); - PyList_SetItem( list, i, cpy); + PyList_Append( list, cpy); + Py_DECREF(cpy); + } + catch(Base::NotImplementedError) { + // silently ignoring extensions not having a Python object + } } } diff --git a/src/Mod/Sketcher/App/GeometryFacadePyImp.cpp b/src/Mod/Sketcher/App/GeometryFacadePyImp.cpp index 1c5d4f8a16..7ea43e12ad 100644 --- a/src/Mod/Sketcher/App/GeometryFacadePyImp.cpp +++ b/src/Mod/Sketcher/App/GeometryFacadePyImp.cpp @@ -297,6 +297,10 @@ PyObject* GeometryFacadePy::getExtensionOfType(PyObject *args) PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not exist anymore."); return 0; } + catch(Base::NotImplementedError) { + PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not implement a Python counterpart."); + return 0; + } } else { @@ -332,7 +336,10 @@ PyObject* GeometryFacadePy::getExtensionOfName(PyObject *args) PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not exist anymore."); return 0; } - + catch(Base::NotImplementedError) { + PyErr_SetString(Part::PartExceptionOCCError, "Geometry extension does not implement a Python counterpart."); + return 0; + } } PyErr_SetString(Part::PartExceptionOCCError, "A string with the name of the geometry extension was expected"); @@ -444,7 +451,7 @@ PyObject* GeometryFacadePy::getExtensions(PyObject *args) try { const std::vector> ext = this->getGeometryFacadePtr()->getExtensions(); - PyObject* list = PyList_New(ext.size()); + PyObject* list = PyList_New(0); for (std::size_t i=0; i(std::const_pointer_cast(p)->getPyObject())->copy(tuple.ptr()); - PyList_SetItem( list, i, cpy); + try { + PyObject* cpy = static_cast(std::const_pointer_cast(p)->getPyObject())->copy(tuple.ptr()); + + PyList_Append( list, cpy); + Py_DECREF(cpy); + } + catch(Base::NotImplementedError) { + // silently ignoring extensions not having a Python object + } } }