From fa6cf560200e9a521366a0da49ae72f8cb0bcc25 Mon Sep 17 00:00:00 2001 From: marioalexis Date: Wed, 20 Jul 2022 01:18:22 -0300 Subject: [PATCH] Gui: Check Python types using Base::PyTypeCheck --- src/Gui/LinkViewPyImp.cpp | 20 ++++++++++---------- src/Gui/MDIViewPy.cpp | 18 +++++++++--------- src/Gui/Selection.cpp | 15 ++++----------- src/Gui/View3DPy.cpp | 19 ++++++++++--------- src/Gui/ViewProviderPy.xml | 18 +++++++++--------- src/Gui/ViewProviderPyImp.cpp | 32 +++++++++++++++++++------------- src/Mod/Part/TestPartGui.py | 6 +++--- 7 files changed, 64 insertions(+), 64 deletions(-) diff --git a/src/Gui/LinkViewPyImp.cpp b/src/Gui/LinkViewPyImp.cpp index a8b10b6e78..c7cccdd198 100644 --- a/src/Gui/LinkViewPyImp.cpp +++ b/src/Gui/LinkViewPyImp.cpp @@ -308,23 +308,23 @@ PyObject* LinkViewPy::getDetailPath(PyObject* args) }PY_CATCH } -PyObject* LinkViewPy::getBoundBox(PyObject* args) { +PyObject* LinkViewPy::getBoundBox(PyObject* args) +{ PyObject *vobj = Py_None; if (!PyArg_ParseTuple(args, "O",&vobj)) return nullptr; - ViewProviderDocumentObject *vpd = nullptr; - if(vobj!=Py_None) { - if(!PyObject_TypeCheck(vobj,&ViewProviderDocumentObjectPy::Type)) { - PyErr_SetString(PyExc_TypeError, "exepcting a type of ViewProviderDocumentObject"); - return nullptr; - } - vpd = static_cast(vobj)->getViewProviderDocumentObjectPtr(); - } + PY_TRY { + Base::PyTypeCheck(&vobj, &ViewProviderDocumentObjectPy::Type); + ViewProviderDocumentObject *vpd = nullptr; + if (vobj) + vpd = static_cast(vobj)->getViewProviderDocumentObjectPtr(); + auto bbox = getLinkViewPtr()->getBoundBox(vpd); Py::Object ret(new Base::BoundBoxPy(new Base::BoundBox3d(bbox))); return Py::new_reference_to(ret); - }PY_CATCH + } + PY_CATCH } PyObject *LinkViewPy::getCustomAttributes(const char*) const diff --git a/src/Gui/MDIViewPy.cpp b/src/Gui/MDIViewPy.cpp index a78bea8ee0..bb89725cdb 100644 --- a/src/Gui/MDIViewPy.cpp +++ b/src/Gui/MDIViewPy.cpp @@ -238,18 +238,18 @@ Py::Object MDIViewPy::setActiveObject(const Py::Tuple& args) if (!PyArg_ParseTuple(args.ptr(), "s|Os", &name, &docObject, &subname)) throw Py::Exception(); - if (_view) { - if (docObject == Py_None) { - _view->setActiveObject(nullptr, name); - } - else { - if (!PyObject_TypeCheck(docObject, &App::DocumentObjectPy::Type)) - throw Py::TypeError("Expect the second argument to be a document object or None"); - - App::DocumentObject* obj = static_cast(docObject)->getDocumentObjectPtr(); + try { + Base::PyTypeCheck(&docObject, &App::DocumentObjectPy::Type, + "Expect the second argument to be a document object or None"); + if (_view) { + App::DocumentObject* obj = docObject ? + static_cast(docObject)->getDocumentObjectPtr() : nullptr; _view->setActiveObject(obj, name, subname); } } + catch (const Base::Exception& e) { + throw Py::Exception(e.getPyExceptionType(), e.what()); + } return Py::None(); } diff --git a/src/Gui/Selection.cpp b/src/Gui/Selection.cpp index 7e34480730..526e5dcabb 100644 --- a/src/Gui/Selection.cpp +++ b/src/Gui/Selection.cpp @@ -2523,17 +2523,10 @@ PyObject *SelectionSingleton::sSetVisible(PyObject * /*self*/, PyObject *args) return nullptr; PY_TRY { - VisibleState vis; - if(visible == Py_None) { - vis = VisToggle; - } - else if (PyBool_Check(visible)) { - vis = Base::asBoolean(visible) ? VisShow : VisHide; - } - else { - PyErr_SetString(PyExc_ValueError, "Argument is neither None nor Bool"); - return nullptr; - } + VisibleState vis = VisToggle; + Base::PyTypeCheck(&visible, &PyBool_Type); + if (visible) + vis = PyObject_IsTrue(visible) ? VisShow : VisHide; Selection().setVisible(vis); Py_Return; diff --git a/src/Gui/View3DPy.cpp b/src/Gui/View3DPy.cpp index 3a09a1c696..d681a964ef 100644 --- a/src/Gui/View3DPy.cpp +++ b/src/Gui/View3DPy.cpp @@ -2566,17 +2566,18 @@ Py::Object View3DInventorPy::setActiveObject(const Py::Tuple& args) if (!PyArg_ParseTuple(args.ptr(), "s|Os", &name, &docObject, &subname)) throw Py::Exception(); - if (docObject == Py_None) { - getView3DIventorPtr()->setActiveObject(nullptr, name); - } - else { - if (!PyObject_TypeCheck(docObject, &App::DocumentObjectPy::Type)) - throw Py::TypeError("Expect the second argument to be a document object or None"); - App::DocumentObject* obj = static_cast(docObject)->getDocumentObjectPtr(); + try { + Base::PyTypeCheck(&docObject, &App::DocumentObjectPy::Type, + "Expect the second argument to be a document object or None"); + App::DocumentObject* obj = docObject ? + static_cast(docObject)->getDocumentObjectPtr() : nullptr; getView3DIventorPtr()->setActiveObject(obj, name, subname); - } - return Py::None(); + return Py::None(); + } + catch (const Base::Exception& e) { + throw Py::Exception(e.getPyExceptionType(), e.what()); + } } Py::Object View3DInventorPy::getActiveObject(const Py::Tuple& args) diff --git a/src/Gui/ViewProviderPy.xml b/src/Gui/ViewProviderPy.xml index 58c7558417..a3adfd3e2f 100644 --- a/src/Gui/ViewProviderPy.xml +++ b/src/Gui/ViewProviderPy.xml @@ -59,10 +59,10 @@ Check if the object is visible. - canDragObject(obj) -> bool\n + canDragObject(obj=None) -> bool\n Check whether the child object can be removed by dragging. If 'obj' is not given, check without filter by any particular object.\n -obj : App.DocumentObject\n Object to be dragged. Optional. +obj : App.DocumentObject\n Object to be dragged. @@ -74,25 +74,25 @@ obj : App.DocumentObject\n Object to be dragged. - canDropObject(obj, owner, subname, elem) -> bool\n + canDropObject(obj=None, owner=None, subname, elem=None) -> bool\n Check whether the child object can be added by dropping. If 'obj' is not given, check without filter by any particular object.\n -obj : App.DocumentObject\n Object to be dropped. Optional. -owner : App.DocumentObject\n Parent object of the dropping object. Optional. +obj : App.DocumentObject\n Object to be dropped. +owner : App.DocumentObject\n Parent object of the dropping object. subname : str\n Subname reference to the dropping object. Optional. elem : sequence of str\n Non-objects subelements selected when the object is - being dropped. Optional. + being dropped. - dropObject(obj, owner, subname, elem) -> str\n + dropObject(obj, owner=None, subname, elem=None) -> str\n Add a child object by dropping.\n obj : App.DocumentObject\n Object to be dropped. -owner : App.DocumentObject\n Parent object of the dropping object. Optional. +owner : App.DocumentObject\n Parent object of the dropping object. subname : str\n Subname reference to the dropping object. Optional. elem : sequence of str\n Non-objects subelements selected when the object is - being dropped. Optional. + being dropped. diff --git a/src/Gui/ViewProviderPyImp.cpp b/src/Gui/ViewProviderPyImp.cpp index 0bdd03563c..8fc2a5f524 100644 --- a/src/Gui/ViewProviderPyImp.cpp +++ b/src/Gui/ViewProviderPyImp.cpp @@ -161,11 +161,12 @@ PyObject* ViewProviderPy::isVisible(PyObject *args) PyObject* ViewProviderPy::canDragObject(PyObject *args) { - PyObject *obj = nullptr; - if (!PyArg_ParseTuple(args, "|O!", &App::DocumentObjectPy::Type, &obj)) + PyObject *obj = Py_None; + if (!PyArg_ParseTuple(args, "|O", &obj)) return nullptr; PY_TRY { + Base::PyTypeCheck(&obj, &App::DocumentObjectPy::Type); bool ret; if (!obj) ret = getViewProviderPtr()->canDragObjects(); @@ -180,17 +181,20 @@ PyObject* ViewProviderPy::canDragObject(PyObject *args) PyObject* ViewProviderPy::canDropObject(PyObject *args, PyObject *kw) { - PyObject *obj = nullptr; - PyObject *owner = nullptr; - PyObject *pyElements = nullptr; + PyObject *obj = Py_None; + PyObject *owner = Py_None; + PyObject *pyElements = Py_None; const char *subname = nullptr; static char* kwlist[] = {"obj","owner","subname","elem",nullptr}; - if (!PyArg_ParseTupleAndKeywords(args, kw, "|O!O!sO", kwlist, - &App::DocumentObjectPy::Type,&obj, &App::DocumentObjectPy::Type, &owner, - &subname, &pyElements)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "|OOsO", kwlist, + &obj, &owner, &subname, &pyElements)) return nullptr; PY_TRY { + Base::PyTypeCheck(&obj, &App::DocumentObjectPy::Type, "expecting 'obj' to be of type App.DocumentObject or None"); + Base::PyTypeCheck(&owner, &App::DocumentObjectPy::Type, "expecting 'owner' to be of type App.DocumentObject or None"); + Base::PyTypeCheck(&pyElements, PySequence_Check, "expecting 'elem' to be sequence or None"); + bool ret; App::DocumentObject* pcObject; App::DocumentObject* pcOwner = nullptr; @@ -238,16 +242,18 @@ PyObject* ViewProviderPy::canDragAndDropObject(PyObject *args) PyObject* ViewProviderPy::dropObject(PyObject *args, PyObject *kw) { PyObject *obj; - PyObject *owner = nullptr; - PyObject *pyElements = nullptr; + PyObject *owner = Py_None; + PyObject *pyElements = Py_None; const char *subname = nullptr; static char* kwlist[] = {"obj","owner","subname","elem",nullptr}; - if (!PyArg_ParseTupleAndKeywords(args, kw, "O!|O!sO", kwlist, - &App::DocumentObjectPy::Type,&obj, &App::DocumentObjectPy::Type, &owner, - &subname, &pyElements)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "O!|OsO", kwlist, + &App::DocumentObjectPy::Type, &obj, &owner, &subname, &pyElements)) return nullptr; PY_TRY { + Base::PyTypeCheck(&owner, &App::DocumentObjectPy::Type, "expecting 'owner' to be of type App.DocumentObject or None"); + Base::PyTypeCheck(&pyElements, PySequence_Check, "expecting 'elem' to be sequence or None"); + auto pcObject = static_cast(obj)->getDocumentObjectPtr(); App::DocumentObject *pcOwner = nullptr; App::PropertyStringList elements; diff --git a/src/Mod/Part/TestPartGui.py b/src/Mod/Part/TestPartGui.py index 7f6b09a906..9fe980ed69 100644 --- a/src/Mod/Part/TestPartGui.py +++ b/src/Mod/Part/TestPartGui.py @@ -49,12 +49,12 @@ class PartGuiViewProviderTestCases(unittest.TestCase): # https://github.com/FreeCAD/FreeCAD/pull/6850 box = self.Doc.addObject("Part::Box", "Box") with self.assertRaises(TypeError): - box.ViewObject.canDragObject(None) + box.ViewObject.canDragObject(0) with self.assertRaises(TypeError): - box.ViewObject.canDropObject(None) + box.ViewObject.canDropObject(0) box.ViewObject.canDropObject() with self.assertRaises(TypeError): - box.ViewObject.dropObject(box, None) + box.ViewObject.dropObject(box, 0) def tearDown(self): #closing doc