? python_exceptions_vtk5.0.diff
? update.log
? Common/vtkPythonUtil.cxx.pyerrevent
? Examples/Build/vtkMyBin
? Examples/GUI/Python/blaat.py
? Examples/Rendering/Python/DataVisDemoText.py
? Wrapping/vtkWrapPython.c.diff-20060802
? Wrapping/Python/vtk/wx/blaat.py
Index: Common/vtkPythonUtil.cxx
===================================================================
RCS file: /cvsroot/VTK/VTK/Common/vtkPythonUtil.cxx,v
retrieving revision 1.76
diff -u -r1.76 vtkPythonUtil.cxx
--- Common/vtkPythonUtil.cxx	4 Aug 2005 16:19:14 -0000	1.76
+++ Common/vtkPythonUtil.cxx	8 Aug 2006 11:45:17 -0000
@@ -19,8 +19,8 @@
 
 #include "vtkSystemIncludes.h"
 
-#include "vtkObject.h"
 #include "vtkObjectFactory.h"
+#include "vtkOutputWindow.h"
 #include "vtkSmartPointerBase.h"
 #include "vtkTimeStamp.h"
 #include "vtkWindows.h"
@@ -50,6 +50,102 @@
 
 //#define VTKPYTHONDEBUG
 
+
+//--------------------------------------------------------------------
+
+
+// these macros should be used to guard calls into Python from
+// C++ code, for example in C++ event handlers and the
+// vtkPythonOutputWindow
+#if (PY_MAJOR_VERSION > 2) || \
+((PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION >= 3))
+#define PyGILBeginMacro PyGILState_STATE state = PyGILState_Ensure();
+#define PyGILEndMacro PyGILState_Release(state);
+#else
+#define PyGILBeginMacro
+#define PyGILEndMacro
+#endif
+
+// .NAME vtkPythonOutputWindow - output window to transform VTK error
+//                               messages to Python exceptions
+// .SECTION Description
+// The Python wrappings set an instance of this class to be the output
+// window.  When any VTK code makes use of e.g. vtkErrorMacro or
+// vtkWarningMacro, this class will turn the error message into a
+// Python RuntimeError exception and a warning into a Python
+// RuntimeWarning.  Debug text will be displayed with the Python
+// 'print' command.  VTK errors and warnings can now be handled in a
+// far more Pythonic way.
+//
+//  -- Charl P. Botha <http://cpbotha.net/>
+class vtkPythonOutputWindow : public vtkOutputWindow
+{
+public:
+  static vtkPythonOutputWindow *New() {
+    return new vtkPythonOutputWindow(); };
+
+  virtual void DisplayText(const char*);
+  virtual void DisplayErrorText(const char*);
+  virtual void DisplayWarningText(const char*);
+  virtual void DisplayGenericWarningText(const char*);
+  virtual void DisplayDebugText(const char*);
+
+protected:
+  vtkPythonOutputWindow() {};
+  ~vtkPythonOutputWindow() {};
+
+private:
+  vtkPythonOutputWindow(const vtkPythonOutputWindow&);  //Not implemented
+  void operator=(const vtkPythonOutputWindow&);  //Not implemented
+};
+
+void vtkPythonOutputWindow::DisplayText(const char* message)
+{
+  char command[4097]; // extra for 0-termination
+  snprintf(command, 4096, "print \"%s\"", message);
+  
+  PyGILBeginMacro;
+
+  PyRun_SimpleString(command);
+
+  PyGILEndMacro;
+}
+
+void vtkPythonOutputWindow::DisplayErrorText(const char* message)
+{
+  PyGILBeginMacro;
+
+  if (!PyErr_Occurred())
+    PyErr_SetString(PyExc_RuntimeError, message);
+
+  PyGILEndMacro;
+}
+
+void vtkPythonOutputWindow::DisplayWarningText(const char* message)
+{
+  PyGILBeginMacro;
+
+  if (!PyErr_Occurred())
+    PyErr_SetString(PyExc_RuntimeWarning, message);
+
+  PyGILEndMacro;
+}
+
+void vtkPythonOutputWindow::DisplayGenericWarningText(const char* message)
+{
+  PyGILBeginMacro;
+
+  if (!PyErr_Occurred())
+    PyErr_SetString(PyExc_RuntimeWarning, message);
+
+  PyGILEndMacro;
+}
+
+void vtkPythonOutputWindow::DisplayDebugText(const char* message)
+{
+  this->DisplayText(message);
+}
+
 //--------------------------------------------------------------------
 // There are two hash tables associated with the Python wrappers
 
@@ -71,6 +167,23 @@
 {
   this->ObjectHash = new vtkstd::map<vtkSmartPointerBase, PyObject*>;
   this->ClassHash = new vtkstd::map<vtkstd::string, PyObject*>;;
+
+#if (PY_MAJOR_VERSION > 2) || \
+    ((PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION >= 3))
+
+  // we need to have this call because we're using
+  // PyGILState_Ensure/Release, see PEP 0311
+  // Python event handlers could be called from different C-threads,
+  // which is why the event handlers use the PyGILState calls.
+  PyEval_InitThreads();
+
+#endif
+
+  // set the vtkPythonOutputWindow as the singleton instance
+  vtkPythonOutputWindow *ow = vtkPythonOutputWindow::New();
+  ow->SetInstance(ow);
+  ow->Delete();
+  
 }
 
 //--------------------------------------------------------------------
@@ -403,6 +516,7 @@
 }
 
 //--------------------------------------------------------------------
+
 static void PyVTKObject_PyDelete(PyVTKObject *self)
 {
 #if PY_VERSION_HEX >= 0x02010000
Index: Wrapping/vtkWrapPython.c
===================================================================
RCS file: /cvsroot/VTK/VTK/Wrapping/vtkWrapPython.c,v
retrieving revision 1.78
diff -u -r1.78 vtkWrapPython.c
--- Wrapping/vtkWrapPython.c	20 Jul 2005 19:10:10 -0000	1.78
+++ Wrapping/vtkWrapPython.c	8 Aug 2006 11:45:19 -0000
@@ -1018,6 +1018,10 @@
                 }
               }
             fprintf(fp,");\n");
+
+
+	    fprintf(fp, "      if (PyErr_Occurred())\n");
+	    fprintf(fp, "        return NULL;\n");
           
             if (currentFunction->NumberOfArguments == 1 
                 && currentFunction->ArgTypes[0] == 0x5000)
