changeset 27:c3cba408a7e6 task

Stop incorrect conversion of multi-row strings. More strict check for undefined values. Check for invalid structure field names. Better error messages. Documentation about dict/list conversion.
author David Grundberg <individ@acc.umu.se>
date Sun, 03 May 2009 20:50:25 +0200
parents 5641245dd9d2
children c9c8ae243701
files octave_to_python.cc package/pytave.py python_to_octave.cc
diffstat 3 files changed, 43 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/octave_to_python.cc	Sun May 03 20:24:48 2009 +0200
+++ b/octave_to_python.cc	Sun May 03 20:50:25 2009 +0200
@@ -261,8 +261,7 @@
 
       if(cell.dim1() != 1) {
          throw value_convert_exception(
-               "Only one dimensional cell arrays are allowed, "
-               "conversion not implemented");
+            "Only one-dimensional (row mayor) cell arrays can be converted.");
       }
 
       for(octave_idx_type i = 0 ; i < cell.length(); i++) {
@@ -290,7 +289,10 @@
 
    void octvalue_to_pyobj(boost::python::object &py_object,
                           const octave_value& octvalue) {
-      if (octvalue.is_scalar_type()) {
+      if (octvalue.is_undefined())
+         throw value_convert_exception(
+            "Octave value `undefined'. Can not convert to a Python object");
+      else if (octvalue.is_scalar_type()) {
          if (octvalue.is_bool_type())
             py_object = object(octvalue.bool_value());
          else if (octvalue.is_real_scalar())
@@ -300,18 +302,18 @@
          else
             throw value_convert_exception(
                "Conversion for this scalar not implemented");
-      } else if (octvalue.is_string())
+      } else if (octvalue.is_string()) {
+         if (octvalue.all_strings().dim1() > 1)
+            throw value_convert_exception(
+               "Multi-row character matrices can not be converted.");
          py_object = str(octvalue.string_value());
-      else if (octvalue.is_matrix_type())
+      } else if (octvalue.is_matrix_type()) {
          octvalue_to_pyarr(py_object, octvalue);
-      else if (octvalue.is_map())
+      } else if (octvalue.is_map()) {
          octmap_to_pyobject(py_object, octvalue.map_value());
-      else if (octvalue.is_cell())
-         octcell_to_pyobject(py_object, octvalue.cell_value());
-      else if (octvalue.is_undefined())
-         throw value_convert_exception(
-            "Octave value `undefined'. Can not convert to a Python object");
-      else
+      } else if (octvalue.is_cell()) {
+         octcell_to_pyobject(py_object, octvalue.cell_value()); 
+      } else
          throw value_convert_exception(
             "Conversion from Octave value not implemented");
    }
--- a/package/pytave.py	Sun May 03 20:24:48 2009 +0200
+++ b/package/pytave.py	Sun May 03 20:50:25 2009 +0200
@@ -50,6 +50,8 @@
 		int (32-bit)        int32
 		float (64-bit)      double
 		str                 string
+		dict                struct
+		list                cell
 		
 	Numeric Array:
 		UBYTE, SBYTE,       matrix of correct type
@@ -67,8 +69,13 @@
 	Scalar values to objects:
 		bool                bool
 		real scalar         float (64-bit)
-		string, sq_string   str
-		str                 string
+		any string*         str
+		struct              dict
+		cell*               list
+
+		* Cell arrays must be one-dimensional (row vector) and
+                  character matrices must only have one row.  Any
+                  other form will raise a ValueConvertError.
 		
 	Matrix values to Numeric arrays:
 		int64               LONG
@@ -106,6 +113,6 @@
 #	fill-column:70
 #	coding:utf-8
 #	indent-tabs-mode:t
-#	tab-width:3
+#	tab-width:8
 #	End:
 # vim: set textwidth=70 noexpandtab tabstop=3 :
--- a/python_to_octave.cc	Sun May 03 20:24:48 2009 +0200
+++ b/python_to_octave.cc	Sun May 03 20:50:25 2009 +0200
@@ -224,9 +224,14 @@
          if(val.is_cell()) {
             const Cell c(val.cell_value());
 
-            if(c.dims().length() == 2 &&
-                  (c.dims()(0) >= 1 && c.dims()(1) > 1) ||
-                  (c.dims()(0) > 1 && c.dims()(1) >= 1)) {
+            // Some things are assumed since we have converted a Python list to
+            // a cell.
+            assert(c.dims().length() == 2);
+            assert(c.dim1() == 1);
+
+            // We do not bother measuring 1x1 values, since they are replicated
+            // to fill up the necessary dimensions.
+            if(c.dims().length() == 2 && c.dim1() != 1 && c.dim2() != 1) {
 
                if(!has_dimensions) {
 
@@ -234,7 +239,7 @@
                   has_dimensions = true;
                } else if(c.dims() != dims) {
                   throw object_convert_exception(
-                        "Dimensions of the parameters to struct do not match");
+                     "Dimensions of the struct fields do not match");
                }
             }
          }
@@ -252,11 +257,20 @@
          boost::python::extract<std::string> str(tuple[0]);
          if(!str.check()) {
             throw object_convert_exception(
-                  "Keys in the python dictionaries must be strings");
+               string("Can not convert key of type ")
+               + PyEval_GetFuncName(boost::python::object(tuple[0]).ptr())
+               + PyEval_GetFuncDesc(boost::python::object(tuple[0]).ptr())
+               + " to a structure field name. Field names must be strings.");
          }
 
          key = str();
 
+         if (!valid_identifier(key)) {
+            throw object_convert_exception(
+               string("Can not convert key `") + key + "' to a structure "
+               "field name. Field names must be valid Octave identifiers.");
+         }
+
          pyobj_to_octvalue(val, tuple[1]);
 
          if(!val.is_cell())