# HG changeset patch # User Mike Miller # Date 1470171192 25200 # Node ID 0d94e42bacf6ec353ce881b844c369e37ce82552 # Parent de98627cf8aee29fbec8aad82fc354d9e89aa133 Convert Octave cell array to Python list (fixes issue #41) * octave_to_python.cc (pytave::octcell_to_pyobject): New function. (pytave::octvalue_to_pyobj): Call octcell_to_pyobject on cell arrays. (pytave::octvalue_to_pyarrobj): Delete cell array case. * pycall.cc: Add %!tests for construction of Python sequence types from cell array. diff -r de98627cf8ae -r 0d94e42bacf6 octave_to_python.cc --- a/octave_to_python.cc Wed Aug 03 21:11:14 2016 -0700 +++ b/octave_to_python.cc Tue Aug 02 13:53:12 2016 -0700 @@ -181,8 +181,6 @@ return create_array (matrix.bool_array_value (), NPY_BOOL); if (matrix.is_string ()) return create_array (matrix.char_array_value (), NPY_CHAR); - if (matrix.is_cell ()) - return create_array (matrix.cell_value (), NPY_OBJECT); throw value_convert_exception ("Octave matrix type not known, conversion not implemented"); } @@ -196,6 +194,26 @@ } static void + octcell_to_pyobject (boost::python::object& py_object, + const Cell& cell) + { + if (! (cell.is_empty () || cell.is_vector ())) + throw value_convert_exception ( + "unable to convert multidimensional cell array into Python sequence"); + + boost::python::list sequence; + + for (octave_idx_type i = 0; i < cell.numel (); i++) + { + boost::python::object py_val; + octvalue_to_pyobj (py_val, cell(i)); + sequence.append (py_val); + } + + py_object = sequence; + } + + static void octmap_to_pyobject (boost::python::object& py_object, const octave_map& map) { @@ -273,8 +291,10 @@ octstring_to_pyobject (py_object, octvalue.string_value ()); else if (octvalue.is_scalar_type ()) octscalar_to_pyobject (py_object, octvalue); + else if (octvalue.is_cell ()) + octcell_to_pyobject (py_object, octvalue.cell_value ()); else if (octvalue.is_numeric_type () || octvalue.is_string () - || octvalue.is_cell () || octvalue.is_bool_type ()) + || octvalue.is_bool_type ()) octvalue_to_pyarr (py_object, octvalue); else if (octvalue.is_map ()) octmap_to_pyobject (py_object, octvalue.map_value ()); diff -r de98627cf8ae -r 0d94e42bacf6 pycall.cc --- a/pycall.cc Wed Aug 03 21:11:14 2016 -0700 +++ b/pycall.cc Tue Aug 02 13:53:12 2016 -0700 @@ -257,6 +257,18 @@ %!assert (pycall ("typename", "Hello world"), "str") %!assert (pycall ("typename", char ([1, 2, 3])), "str") +## Test construction of sequence types from cell arrays +%!assert (char (pycall ("list")), "[]") +%!assert (char (pycall ("list", {})), "[]") +%!assert (char (pycall ("list", {1, 2, 3})), "[1.0, 2.0, 3.0]") +%!assert (char (pycall ("list", {int8(1), int8(2), int8(3)})), "[1, 2, 3]") +%!assert (char (pycall ("tuple")), "()") +%!assert (char (pycall ("tuple", {})), "()") +%!assert (char (pycall ("tuple", {1, 2, 3})), "(1.0, 2.0, 3.0)") +%!assert (char (pycall ("tuple", {int8(1), int8(2), int8(3)})), "(1, 2, 3)") +%!error (pycall ("list", {1, 2, 3; 4, 5, 6})) +%!error (pycall ("dict", {1, 2, 3})) + ## Test round trip type preservation / conversion %!test %! pyexec ("def roundtrip(x): return x");