From 10a13c6dbc240359e9bd07c0cbd45b2487555b92 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 17 Mar 2022 11:29:09 +0100 Subject: [PATCH] Base: add more custom Python exception types --- src/App/Application.cpp | 73 ++++++++++++++++++++--- src/App/Application.h | 2 + src/Base/Exception.cpp | 118 ++++++++++++++++++++++++++++++++------ src/Base/Exception.h | 64 +++++++++++++-------- src/Base/PyObjectBase.cpp | 9 +++ src/Base/PyObjectBase.h | 9 +++ 6 files changed, 227 insertions(+), 48 deletions(-) diff --git a/src/App/Application.cpp b/src/App/Application.cpp index a2c9b41b25..da01a977ae 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -163,8 +163,19 @@ Base::ConsoleObserverStd *Application::_pConsoleObserverStd = nullptr; Base::ConsoleObserverFile *Application::_pConsoleObserverFile = nullptr; AppExport std::map Application::mConfig; + +// Custom Python exception types BaseExport extern PyObject* Base::BaseExceptionFreeCADError; BaseExport extern PyObject* Base::BaseExceptionFreeCADAbort; +BaseExport extern PyObject* Base::PyExc_FC_XMLBaseException; +BaseExport extern PyObject* Base::PyExc_FC_XMLParseException; +BaseExport extern PyObject* Base::PyExc_FC_XMLAttributeError; +BaseExport extern PyObject* Base::PyExc_FC_UnknownProgramOption; +BaseExport extern PyObject* Base::PyExc_FC_BadFormatError; +BaseExport extern PyObject* Base::PyExc_FC_BadGraphError; +BaseExport extern PyObject* Base::PyExc_FC_ExpressionError; +BaseExport extern PyObject* Base::PyExc_FC_ParserError; +BaseExport extern PyObject* Base::PyExc_FC_CADKernelError; //************************************************************************** // Construction and destruction @@ -225,7 +236,15 @@ Application::Application(std::map &mConfig) mpcPramManager["System parameter"] = _pcSysParamMngr; mpcPramManager["User parameter"] = _pcUserParamMngr; + setupPythonTypes(); +} +Application::~Application() +{ +} + +void Application::setupPythonTypes() +{ // setting up Python binding Base::PyGILStateLocker lock; PyObject* modules = PyImport_GetModuleDict(); @@ -270,13 +289,8 @@ Application::Application(std::map &mConfig) PyDict_SetItemString(modules, "__FreeCADBase__", pBaseModule); } - Base::BaseExceptionFreeCADError = PyErr_NewException("Base.FreeCADError", PyExc_RuntimeError, nullptr); - Py_INCREF(Base::BaseExceptionFreeCADError); - PyModule_AddObject(pBaseModule, "FreeCADError", Base::BaseExceptionFreeCADError); + setupPythonException(pBaseModule); - Base::BaseExceptionFreeCADAbort = PyErr_NewException("Base.FreeCADAbort", PyExc_BaseException, nullptr); - Py_INCREF(Base::BaseExceptionFreeCADAbort); - PyModule_AddObject(pBaseModule, "FreeCADAbort", Base::BaseExceptionFreeCADAbort); // Python types Base::Interpreter().addType(&Base::VectorPy ::Type,pBaseModule,"Vector"); @@ -343,8 +357,53 @@ Application::Application(std::map &mConfig) pBaseModule,"Vector2d"); } -Application::~Application() +void Application::setupPythonException(PyObject* module) { + // Define cusom Python exception types + // + Base::BaseExceptionFreeCADError = PyErr_NewException("Base.FreeCADError", PyExc_RuntimeError, nullptr); + Py_INCREF(Base::BaseExceptionFreeCADError); + PyModule_AddObject(module, "FreeCADError", Base::BaseExceptionFreeCADError); + + Base::BaseExceptionFreeCADAbort = PyErr_NewException("Base.FreeCADAbort", PyExc_BaseException, nullptr); + Py_INCREF(Base::BaseExceptionFreeCADAbort); + PyModule_AddObject(module, "FreeCADAbort", Base::BaseExceptionFreeCADAbort); + + Base::PyExc_FC_XMLBaseException = PyErr_NewException("Base.XMLBaseException", PyExc_BaseException, nullptr); + Py_INCREF(Base::PyExc_FC_XMLBaseException); + PyModule_AddObject(module, "XMLBaseException", Base::PyExc_FC_XMLBaseException); + + Base::PyExc_FC_XMLParseException = PyErr_NewException("Base.XMLParseException", Base::PyExc_FC_XMLBaseException, nullptr); + Py_INCREF(Base::PyExc_FC_XMLParseException); + PyModule_AddObject(module, "XMLParseException", Base::PyExc_FC_XMLParseException); + + Base::PyExc_FC_XMLAttributeError = PyErr_NewException("Base.XMLAttributeError", Base::PyExc_FC_XMLBaseException, nullptr); + Py_INCREF(Base::PyExc_FC_XMLAttributeError); + PyModule_AddObject(module, "XMLAttributeError", Base::PyExc_FC_XMLAttributeError); + + Base::PyExc_FC_UnknownProgramOption = PyErr_NewException("Base.UnknownProgramOption", PyExc_BaseException, nullptr); + Py_INCREF(Base::PyExc_FC_UnknownProgramOption); + PyModule_AddObject(module, "UnknownProgramOption", Base::PyExc_FC_UnknownProgramOption); + + Base::PyExc_FC_BadFormatError = PyErr_NewException("Base.BadFormatError", PyExc_BaseException, nullptr); + Py_INCREF(Base::PyExc_FC_BadFormatError); + PyModule_AddObject(module, "BadFormatError", Base::PyExc_FC_BadFormatError); + + Base::PyExc_FC_BadGraphError = PyErr_NewException("Base.BadGraphError", PyExc_BaseException, nullptr); + Py_INCREF(Base::PyExc_FC_BadGraphError); + PyModule_AddObject(module, "BadGraphError", Base::PyExc_FC_BadGraphError); + + Base::PyExc_FC_ExpressionError = PyErr_NewException("Base.ExpressionError", PyExc_BaseException, nullptr); + Py_INCREF(Base::PyExc_FC_ExpressionError); + PyModule_AddObject(module, "ExpressionError", Base::PyExc_FC_ExpressionError); + + Base::PyExc_FC_ParserError = PyErr_NewException("Base.ParserError", PyExc_BaseException, nullptr); + Py_INCREF(Base::PyExc_FC_ParserError); + PyModule_AddObject(module, "ParserError", Base::PyExc_FC_ParserError); + + Base::PyExc_FC_CADKernelError = PyErr_NewException("Base.CADKernelError", PyExc_BaseException, nullptr); + Py_INCREF(Base::PyExc_FC_CADKernelError); + PyModule_AddObject(module, "CADKernelError", Base::PyExc_FC_CADKernelError); } //************************************************************************** diff --git a/src/App/Application.h b/src/App/Application.h index 91aa6d26e2..27ea6dd37a 100644 --- a/src/App/Application.h +++ b/src/App/Application.h @@ -502,6 +502,8 @@ private: //--------------------------------------------------------------------- // python exports goes here +++++++++++++++++++++++++++++++++++++++++++ //--------------------------------------------------------------------- + static void setupPythonTypes(); + static void setupPythonException(PyObject*); // static python wrapper of the exported functions static PyObject* sGetParam (PyObject *self,PyObject *args); diff --git a/src/Base/Exception.cpp b/src/Base/Exception.cpp index ff8e2fb428..4bc13ee0da 100644 --- a/src/Base/Exception.cpp +++ b/src/Base/Exception.cpp @@ -202,6 +202,11 @@ XMLBaseException::XMLBaseException(const std::string& sMessage) { } +PyObject * XMLBaseException::getPyExceptionType() const +{ + return PyExc_FC_XMLBaseException; +} + // --------------------------------------------------------- XMLParseException::XMLParseException(const char * sMessage) @@ -224,6 +229,11 @@ const char* XMLParseException::what() const throw() return XMLBaseException::what(); } +PyObject * XMLParseException::getPyExceptionType() const +{ + return PyExc_FC_XMLParseException; +} + // --------------------------------------------------------- XMLAttributeError::XMLAttributeError(const char * sMessage) @@ -246,6 +256,11 @@ const char* XMLAttributeError::what() const throw() return XMLBaseException::what(); } +PyObject * XMLAttributeError::getPyExceptionType() const +{ + return PyExc_FC_XMLAttributeError; +} + // --------------------------------------------------------- @@ -274,7 +289,8 @@ FileException::FileException(const FileException &inst) { } -void FileException::setFileName(const char * sFileName) { +void FileException::setFileName(const char * sFileName) +{ file.setFile(sFileName); _sErrMsgAndFileName = _sErrMsg; if (sFileName) { @@ -337,7 +353,8 @@ void FileException::setPyObject( PyObject * pydict) } } -PyObject * FileException::getPyExceptionType() const { +PyObject * FileException::getPyExceptionType() const +{ return PyExc_IOError; } @@ -359,6 +376,11 @@ FileSystemError::FileSystemError(const std::string& sMessage) { } +PyObject * FileSystemError::getPyExceptionType() const +{ + return PyExc_IOError; +} + // --------------------------------------------------------- @@ -377,6 +399,11 @@ BadFormatError::BadFormatError(const std::string& sMessage) { } +PyObject * BadFormatError::getPyExceptionType() const +{ + return PyExc_FC_BadFormatError; +} + // --------------------------------------------------------- @@ -408,6 +435,11 @@ const char* MemoryException::what() const throw() } #endif +PyObject * MemoryException::getPyExceptionType() const +{ + return PyExc_MemoryError; +} + // --------------------------------------------------------- AccessViolation::AccessViolation() @@ -425,6 +457,11 @@ AccessViolation::AccessViolation(const std::string& sMessage) { } +PyObject *AccessViolation::getPyExceptionType() const +{ + return PyExc_OSError; +} + // --------------------------------------------------------- AbnormalProgramTermination::AbnormalProgramTermination() @@ -442,6 +479,11 @@ AbnormalProgramTermination::AbnormalProgramTermination(const std::string& sMessa { } +PyObject *AbnormalProgramTermination::getPyExceptionType() const +{ + return PyExc_InterruptedError; +} + // --------------------------------------------------------- UnknownProgramOption::UnknownProgramOption() @@ -459,6 +501,11 @@ UnknownProgramOption::UnknownProgramOption(const std::string& sMessage) { } +PyObject *UnknownProgramOption::getPyExceptionType() const +{ + return PyExc_FC_UnknownProgramOption; +} + // --------------------------------------------------------- ProgramInformation::ProgramInformation() @@ -493,7 +540,8 @@ TypeError::TypeError(const std::string& sMessage) { } -PyObject *TypeError::getPyExceptionType() const { +PyObject *TypeError::getPyExceptionType() const +{ return PyExc_TypeError; } @@ -514,7 +562,8 @@ ValueError::ValueError(const std::string& sMessage) { } -PyObject *ValueError::getPyExceptionType() const { +PyObject *ValueError::getPyExceptionType() const +{ return PyExc_ValueError; } @@ -535,7 +584,8 @@ IndexError::IndexError(const std::string& sMessage) { } -PyObject *IndexError::getPyExceptionType() const { +PyObject *IndexError::getPyExceptionType() const +{ return PyExc_IndexError; } @@ -556,7 +606,8 @@ NameError::NameError(const std::string& sMessage) { } -PyObject *NameError::getPyExceptionType() const { +PyObject *NameError::getPyExceptionType() const +{ return PyExc_NameError; } @@ -577,7 +628,8 @@ ImportError::ImportError(const std::string& sMessage) { } -PyObject *ImportError::getPyExceptionType() const { +PyObject *ImportError::getPyExceptionType() const +{ return PyExc_ImportError; } @@ -598,7 +650,8 @@ AttributeError::AttributeError(const std::string& sMessage) { } -PyObject *AttributeError::getPyExceptionType() const { +PyObject *AttributeError::getPyExceptionType() const +{ return PyExc_AttributeError; } @@ -619,7 +672,8 @@ RuntimeError::RuntimeError(const std::string& sMessage) { } -PyObject *RuntimeError::getPyExceptionType() const { +PyObject *RuntimeError::getPyExceptionType() const +{ return PyExc_RuntimeError; } @@ -640,6 +694,11 @@ BadGraphError::BadGraphError(const std::string& sMessage) { } +PyObject *BadGraphError::getPyExceptionType() const +{ + return PyExc_FC_BadGraphError; +} + // --------------------------------------------------------- NotImplementedError::NotImplementedError() @@ -657,7 +716,8 @@ NotImplementedError::NotImplementedError(const std::string& sMessage) { } -PyObject *NotImplementedError::getPyExceptionType() const { +PyObject *NotImplementedError::getPyExceptionType() const +{ return PyExc_NotImplementedError; } @@ -678,7 +738,8 @@ ZeroDivisionError::ZeroDivisionError(const std::string& sMessage) { } -PyObject *ZeroDivisionError::getPyExceptionType() const { +PyObject *ZeroDivisionError::getPyExceptionType() const +{ return PyExc_ZeroDivisionError; } @@ -699,7 +760,8 @@ ReferenceError::ReferenceError(const std::string& sMessage) { } -PyObject *ReferenceError::getPyExceptionType() const { +PyObject *ReferenceError::getPyExceptionType() const +{ return PyExc_ReferenceError; } @@ -720,6 +782,11 @@ ExpressionError::ExpressionError(const std::string& sMessage) { } +PyObject * ExpressionError::getPyExceptionType() const +{ + return PyExc_FC_ExpressionError; +} + // --------------------------------------------------------- ParserError::ParserError() @@ -737,6 +804,11 @@ ParserError::ParserError(const std::string& sMessage) { } +PyObject * ParserError::getPyExceptionType() const +{ + return PyExc_FC_ParserError; +} + // --------------------------------------------------------- UnicodeError::UnicodeError() @@ -754,7 +826,8 @@ UnicodeError::UnicodeError(const std::string& sMessage) { } -PyObject *UnicodeError::getPyExceptionType() const { +PyObject *UnicodeError::getPyExceptionType() const +{ return PyExc_UnicodeError; } @@ -775,7 +848,8 @@ OverflowError::OverflowError(const std::string& sMessage) { } -PyObject *OverflowError::getPyExceptionType() const { +PyObject *OverflowError::getPyExceptionType() const +{ return PyExc_OverflowError; } @@ -796,7 +870,8 @@ UnderflowError::UnderflowError(const std::string& sMessage) { } -PyObject *UnderflowError::getPyExceptionType() const { +PyObject *UnderflowError::getPyExceptionType() const +{ return PyExc_ArithmeticError; } @@ -817,7 +892,8 @@ UnitsMismatchError::UnitsMismatchError(const std::string& sMessage) { } -PyObject *UnitsMismatchError::getPyExceptionType() const { +PyObject *UnitsMismatchError::getPyExceptionType() const +{ return PyExc_ArithmeticError; } @@ -838,6 +914,11 @@ CADKernelError::CADKernelError(const std::string& sMessage) { } +PyObject * CADKernelError::getPyExceptionType() const +{ + return PyExc_FC_CADKernelError; +} + // --------------------------------------------------------- RestoreError::RestoreError() @@ -855,6 +936,11 @@ RestoreError::RestoreError(const std::string& sMessage) { } +PyObject * RestoreError::getPyExceptionType() const +{ + return PyExc_IOError; +} + // --------------------------------------------------------- #if defined(__GNUC__) && defined (FC_OS_LINUX) diff --git a/src/Base/Exception.h b/src/Base/Exception.h index 7163c0cbf6..044f11b935 100644 --- a/src/Base/Exception.h +++ b/src/Base/Exception.h @@ -157,7 +157,7 @@ protected: */ class BaseExport AbortException : public Exception { - TYPESYSTEM_HEADER(); + TYPESYSTEM_HEADER_WITH_OVERRIDE(); public: /// Construction AbortException(const char * sMessage); @@ -167,9 +167,9 @@ public: /// Destruction virtual ~AbortException() throw() {} /// Description of the exception - virtual const char* what() const throw(); + const char* what() const throw() override; /// returns the corresponding python exception type - virtual PyObject * getPyExceptionType() const; + PyObject * getPyExceptionType() const override; }; /** @@ -186,6 +186,7 @@ public: /// Destruction virtual ~XMLBaseException() throw() {} + PyObject * getPyExceptionType() const override; }; /** @@ -205,7 +206,8 @@ public: /// Destruction virtual ~XMLParseException() throw() {} /// Description of the exception - virtual const char* what() const throw(); + const char* what() const throw() override; + PyObject * getPyExceptionType() const override; }; /** @@ -225,7 +227,8 @@ public: /// Destruction virtual ~XMLAttributeError() throw() {} /// Description of the exception - virtual const char* what() const throw(); + const char* what() const throw() override; + PyObject * getPyExceptionType() const override; }; /** File exception handling class @@ -248,17 +251,17 @@ public: /// Assignment operator FileException &operator=(const FileException &inst); /// Description of the exception - virtual const char* what() const throw() override; + const char* what() const throw() override; /// Report generation - virtual void ReportException () const override; + void ReportException () const override; /// Get file name for use with translatable message std::string getFileName() const; /// returns a Python dictionary containing the exception data - virtual PyObject * getPyObject() override; + PyObject * getPyObject() override; /// returns sets the exception data from a Python dictionary - virtual void setPyObject( PyObject * pydict) override; + void setPyObject( PyObject * pydict) override; - virtual PyObject * getPyExceptionType() const override; + PyObject * getPyExceptionType() const override; protected: FileInfo file; // necessary for what() legacy behaviour as it returns a buffer that @@ -281,6 +284,7 @@ public: FileSystemError(const std::string& sMessage); /// Destruction virtual ~FileSystemError() throw() {} + PyObject * getPyExceptionType() const override; }; /** @@ -296,6 +300,7 @@ public: BadFormatError(const std::string& sMessage); /// Destruction virtual ~BadFormatError() throw() {} + PyObject * getPyExceptionType() const override; }; /** @@ -320,8 +325,9 @@ public: MemoryException &operator=(const MemoryException &inst); #if defined (__GNUC__) /// Description of the exception - virtual const char* what() const throw() override; + const char* what() const throw() override; #endif + PyObject * getPyExceptionType() const override; }; /** @@ -337,6 +343,7 @@ public: AccessViolation(const std::string& sMessage); /// Destruction virtual ~AccessViolation() throw() {} + PyObject * getPyExceptionType() const override; }; /** @@ -353,6 +360,7 @@ public: AbnormalProgramTermination(const std::string& sMessage); /// Destruction virtual ~AbnormalProgramTermination() throw() {} + PyObject * getPyExceptionType() const override; }; /** @@ -368,6 +376,7 @@ public: UnknownProgramOption(const std::string& sMessage); /// Destruction virtual ~UnknownProgramOption() throw() {} + PyObject * getPyExceptionType() const override; }; /** @@ -399,7 +408,7 @@ public: TypeError(const std::string& sMessage); /// Destruction virtual ~TypeError() throw() {} - virtual PyObject * getPyExceptionType() const override; + PyObject * getPyExceptionType() const override; }; /** @@ -415,7 +424,7 @@ public: ValueError(const std::string& sMessage); /// Destruction virtual ~ValueError() throw() {} - virtual PyObject * getPyExceptionType() const override; + PyObject * getPyExceptionType() const override; }; /** @@ -431,7 +440,7 @@ public: IndexError(const std::string& sMessage); /// Destruction virtual ~IndexError() throw() {} - virtual PyObject * getPyExceptionType() const override; + PyObject * getPyExceptionType() const override; }; class BaseExport NameError : public Exception @@ -443,7 +452,7 @@ public: NameError(const std::string& sMessage); /// Destruction virtual ~NameError() throw() {} - virtual PyObject * getPyExceptionType() const override; + PyObject * getPyExceptionType() const override; }; class BaseExport ImportError : public Exception @@ -455,7 +464,7 @@ public: ImportError(const std::string& sMessage); /// Destruction virtual ~ImportError() throw() {} - virtual PyObject * getPyExceptionType() const override; + PyObject * getPyExceptionType() const override; }; /** @@ -471,7 +480,7 @@ public: AttributeError(const std::string& sMessage); /// Destruction virtual ~AttributeError() throw() {} - virtual PyObject * getPyExceptionType() const override; + PyObject * getPyExceptionType() const override; }; /** @@ -487,7 +496,7 @@ public: RuntimeError(const std::string& sMessage); /// Destruction virtual ~RuntimeError() throw() {} - virtual PyObject * getPyExceptionType() const override; + PyObject * getPyExceptionType() const override; }; /** @@ -503,6 +512,7 @@ public: BadGraphError(const std::string& sMessage); /// Destruction virtual ~BadGraphError() throw() {} + PyObject * getPyExceptionType() const; }; /** @@ -518,7 +528,7 @@ public: NotImplementedError(const std::string& sMessage); /// Destruction virtual ~NotImplementedError() throw() {} - virtual PyObject * getPyExceptionType() const override; + PyObject * getPyExceptionType() const override; }; /** @@ -534,7 +544,7 @@ public: ZeroDivisionError(const std::string& sMessage); /// Destruction virtual ~ZeroDivisionError() throw() {} - virtual PyObject * getPyExceptionType() const override; + PyObject * getPyExceptionType() const override; }; /** @@ -550,7 +560,7 @@ public: ReferenceError(const std::string& sMessage); /// Destruction virtual ~ReferenceError() throw() {} - virtual PyObject * getPyExceptionType() const override; + PyObject * getPyExceptionType() const override; }; /** @@ -567,6 +577,7 @@ public: ExpressionError(const std::string& sMessage); /// Destruction virtual ~ExpressionError() throw() {} + PyObject * getPyExceptionType() const override; }; /** @@ -582,6 +593,7 @@ public: ParserError(const std::string& sMessage); /// Destruction virtual ~ParserError() throw() {} + PyObject * getPyExceptionType() const override; }; /** @@ -597,7 +609,7 @@ public: UnicodeError(const std::string& sMessage); /// Destruction virtual ~UnicodeError() throw() {} - virtual PyObject * getPyExceptionType() const override; + PyObject * getPyExceptionType() const override; }; /** @@ -613,7 +625,7 @@ public: OverflowError(const std::string& sMessage); /// Destruction virtual ~OverflowError() throw() {} - virtual PyObject * getPyExceptionType() const override; + PyObject * getPyExceptionType() const override; }; /** @@ -629,7 +641,7 @@ public: UnderflowError(const std::string& sMessage); /// Destruction virtual ~UnderflowError() throw() {} - virtual PyObject * getPyExceptionType() const override; + PyObject * getPyExceptionType() const override; }; /** @@ -645,7 +657,7 @@ public: UnitsMismatchError(const std::string& sMessage); /// Destruction virtual ~UnitsMismatchError() throw() {} - virtual PyObject * getPyExceptionType() const override; + PyObject * getPyExceptionType() const override; }; /* The CADKernelError can be used to indicate an exception originating in the CAD Kernel @@ -662,6 +674,7 @@ public: CADKernelError(const std::string& sMessage); /// Destruction virtual ~CADKernelError() throw() {} + PyObject * getPyExceptionType() const; }; /* The RestoreError can be used to try to do a best recovery effort when an error during restoring @@ -680,6 +693,7 @@ public: RestoreError(const std::string& sMessage); /// Destruction virtual ~RestoreError() throw() {} + PyObject * getPyExceptionType() const override; }; diff --git a/src/Base/PyObjectBase.cpp b/src/Base/PyObjectBase.cpp index 7336963e7b..024dadb753 100644 --- a/src/Base/PyObjectBase.cpp +++ b/src/Base/PyObjectBase.cpp @@ -38,6 +38,15 @@ using namespace Base; PyObject* Base::BaseExceptionFreeCADError = nullptr; PyObject* Base::BaseExceptionFreeCADAbort = nullptr; +PyObject* Base::PyExc_FC_XMLBaseException = nullptr; +PyObject* Base::PyExc_FC_XMLParseException = nullptr; +PyObject* Base::PyExc_FC_XMLAttributeError = nullptr; +PyObject* Base::PyExc_FC_UnknownProgramOption = nullptr; +PyObject* Base::PyExc_FC_BadFormatError = nullptr; +PyObject* Base::PyExc_FC_BadGraphError = nullptr; +PyObject* Base::PyExc_FC_ExpressionError = nullptr; +PyObject* Base::PyExc_FC_ParserError = nullptr; +PyObject* Base::PyExc_FC_CADKernelError = nullptr; typedef struct { PyObject_HEAD diff --git a/src/Base/PyObjectBase.h b/src/Base/PyObjectBase.h index fb0388100b..45bb3a1857 100644 --- a/src/Base/PyObjectBase.h +++ b/src/Base/PyObjectBase.h @@ -415,6 +415,15 @@ BaseExport extern PyObject* BaseExceptionFreeCADError; BaseExceptionFreeCADError : PyExc_RuntimeError) BaseExport extern PyObject* BaseExceptionFreeCADAbort; +BaseExport extern PyObject* PyExc_FC_XMLBaseException; +BaseExport extern PyObject* PyExc_FC_XMLParseException; +BaseExport extern PyObject* PyExc_FC_XMLAttributeError; +BaseExport extern PyObject* PyExc_FC_UnknownProgramOption; +BaseExport extern PyObject* PyExc_FC_BadFormatError; +BaseExport extern PyObject* PyExc_FC_BadGraphError; +BaseExport extern PyObject* PyExc_FC_ExpressionError; +BaseExport extern PyObject* PyExc_FC_ParserError; +BaseExport extern PyObject* PyExc_FC_CADKernelError; /** Exception handling for python callback functions * Is a convenience macro to manage the exception handling of python callback