[glom] Python: Really show warnings when modules can't be imported.



commit 6c2ffabf2e4d0cc39d93de8cd244d1401a0a5819
Author: Murray Cumming <murrayc murrayc com>
Date:   Fri Apr 16 22:02:43 2010 +0200

    Python: Really show warnings when modules can't be imported.
    
    * glom/python_embed/glom_python.cc: Add and use import_module() to make sure
    that we catch exceptions from boost::python::import(), so show the intended
    warnings instead of just crashing with an uncaught exception.
    Also correct the checks for empty/none boost::python::objects for imported
    modules. A simple ! is not what it seems.

 ChangeLog                        |   10 ++++++
 glom/python_embed/glom_python.cc |   60 ++++++++++++++++++++++---------------
 2 files changed, 46 insertions(+), 24 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 3d40a6d..4575056 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2010-04-16  Murray Cumming  <murrayc murrayc com>
 
+	Python: Really show warnings when modules can't be imported.
+	
+	* glom/python_embed/glom_python.cc: Add and use import_module() to make sure 
+	that we catch exceptions from boost::python::import(), so show the intended 
+	warnings instead of just crashing with an uncaught exception.
+	Also correct the checks for empty/none boost::python::objects for imported 
+	modules. A simple ! is not what it seems.
+
+2010-04-16  Murray Cumming  <murrayc murrayc com>
+
     Use mm-common for optional compiler warnings and to build libglom docs.
 
     * configure.ac: Use mm-common, removing macros/dk-warn.m4.
diff --git a/glom/python_embed/glom_python.cc b/glom/python_embed/glom_python.cc
index bdcebd3..f3d79bd 100644
--- a/glom/python_embed/glom_python.cc
+++ b/glom/python_embed/glom_python.cc
@@ -138,30 +138,42 @@ void ShowTrace()
   g_free(chrRetval);
 }
 
-bool glom_python_module_is_available()
+/** Import a python module, warning about exceptions.
+ * Compare with boost::python::object() to detect failure.
+ */
+static boost::python::object import_module(const char* name)
 {
-  const gchar* name = "glom_" GLOM_ABI_VERSION_UNDERLINED;
-  boost::python::object module_glom = boost::python::import(name);
+  boost::python::object module_glom; //Defaults to PyNone. 
+  try
+  {
+    module_glom = boost::python::import(name);
+  }
+  catch(const boost::python::error_already_set& ex)
+  {
+    std::cerr << "boost::python::import() failed while importing module: "<< name << std::endl;
+    ShowTrace();
+  }
 
-  if(!module_glom)
+  if(module_glom == boost::python::object())
   {
-    g_warning("Glom: A python import of %s failed.\n", name);
+    std::cerr << "Glom: A python import of a module failed: " << name << std::endl;
   }
 
-  return module_glom != 0;
+  return module_glom;
 }
 
-bool gda_python_module_is_available()
+bool glom_python_module_is_available()
 {
-  const gchar* name = "gda";
-  boost::python::object module_glom = boost::python::import(name); //TODO: unref this?
-
-  if(!module_glom)
-  {
-    g_warning("Glom: A python import of %s failed.\n", name);
-  }
+  const char* name = "glom_" GLOM_ABI_VERSION_UNDERLINED;
+  const boost::python::object module_glom = import_module(name);
+  return module_glom != boost::python::object();
+}
 
-  return module_glom != 0;
+bool gda_python_module_is_available()
+{
+  const char* name = "gda";
+  const boost::python::object module_glom = import_module(name);
+  return module_glom != boost::python::object();
 }
 
 static boost::python::object glom_python_call(Field::glom_field_type result_type,
@@ -205,7 +217,7 @@ static boost::python::object glom_python_call(Field::glom_field_type result_type
   
   //We did this in main(): Py_Initialize();
 
-  boost::python::object pMain = boost::python::import("__main__");
+  boost::python::object pMain = import_module("__main__");
   boost::python::object pDict(pMain.attr("__dict__")); //TODO: Does boost::python have an equivalent for PyModule_GetDict()?
   //TODO: Complain that this doesn't work:
   //boost::python::dict pDict = pMain.attr("__dict__"); //TODO: Does boost::python have an equivalent for PyModule_GetDict()?
@@ -245,16 +257,16 @@ static boost::python::object glom_python_call(Field::glom_field_type result_type
   }
 
   //TODO: Is this necessary?
-  boost::python::object module_glom = boost::python::import("glom_" GLOM_ABI_VERSION_UNDERLINED);
-  if(!module_glom)
+  boost::python::object module_glom = import_module("glom_" GLOM_ABI_VERSION_UNDERLINED);
+  if(module_glom == boost::python::object())
   {
     g_warning("Could not import python glom module.");
     return boost::python::object(); // don't crash
   }
 
   //TODO: Is this necessary?
-  boost::python::object module_gda = boost::python::import("gda");
-  if(!module_gda)
+  boost::python::object module_gda = import_module("gda");
+  if(module_gda == boost::python::object())
   {
     g_warning("Could not import python gda module.");
     return boost::python::object();
@@ -369,8 +381,8 @@ void glom_execute_python_function_implementation(const Glib::ustring& func_impl,
   const PythonUICallbacks& callbacks)
 {
   //Import the glom module so that boost::python::object(new PyGlomRecord) can work.
-  boost::python::object module_glom = boost::python::import("glom_" GLOM_ABI_VERSION_UNDERLINED);
-  if(!module_glom)
+  boost::python::object module_glom = import_module("glom_" GLOM_ABI_VERSION_UNDERLINED);
+  if(module_glom == boost::python::object())
   {
     g_warning("Could not import python glom module.");
     return; // don't crash
@@ -407,8 +419,8 @@ Gnome::Gda::Value glom_evaluate_python_function_implementation(Field::glom_field
   const Glib::RefPtr<Gnome::Gda::Connection>& opened_connection)
 {
   //Import the glom module so that boost::python::object(new PyGlomRecord) can work.
-  boost::python::object module_glom = boost::python::import("glom_" GLOM_ABI_VERSION_UNDERLINED);
-  if(!module_glom)
+  boost::python::object module_glom = import_module("glom_" GLOM_ABI_VERSION_UNDERLINED);
+  if(module_glom == boost::python::object())
   {
     g_warning("Could not import python glom module.");
     return Gnome::Gda::Value(); // don't crash



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]