changeset 197:d6c44d680482

Convert Octave scalars into Python scalars (fixes issue #14) * octave_to_python.cc (octscalar_to_pyobject): New function. (octvalue_to_pyobj): Call it when argument is a scalar. * pycall.cc: Enable previously failing tests for scalar type conversion.
author Mike Miller <mtmiller@octave.org>
date Thu, 14 Jul 2016 23:56:40 -0700
parents 43e92dd60dd0
children 377f2dc057ea
files octave_to_python.cc pycall.cc
diffstat 2 files changed, 51 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/octave_to_python.cc	Thu Jul 14 23:42:45 2016 -0700
+++ b/octave_to_python.cc	Thu Jul 14 23:56:40 2016 -0700
@@ -211,6 +211,45 @@
   }
 
   static void
+  octscalar_to_pyobject (boost::python::object& py_object,
+                         const octave_value& arg)
+  {
+    PyObject *obj = 0;
+
+    if (arg.is_complex_type ())
+      obj = PyComplex_FromDoubles (arg.real ().double_value (),
+                                   arg.imag ().double_value ());
+    else if (arg.is_float_type ())
+      obj = PyFloat_FromDouble (arg.double_value ());
+
+    else if (arg.is_int8_type ())
+      obj = PyLong_FromLong (arg.int8_scalar_value ().value ());
+    else if (arg.is_int16_type ())
+      obj = PyLong_FromLong (arg.int16_scalar_value ().value ());
+    else if (arg.is_int32_type ())
+      obj = PyLong_FromLong (arg.int32_scalar_value ().value ());
+    else if (arg.is_int64_type ())
+      obj = PyLong_FromLong (arg.int64_scalar_value ().value ());
+
+    else if (arg.is_uint8_type ())
+      obj = PyLong_FromUnsignedLong (arg.uint8_scalar_value ().value ());
+    else if (arg.is_uint16_type ())
+      obj = PyLong_FromUnsignedLong (arg.uint16_scalar_value ().value ());
+    else if (arg.is_uint32_type ())
+      obj = PyLong_FromUnsignedLong (arg.uint32_scalar_value ().value ());
+    else if (arg.is_uint64_type ())
+      obj = PyLong_FromUnsignedLong (arg.uint64_scalar_value ().value ());
+
+    else if (arg.is_bool_type ())
+      obj = PyBool_FromLong (arg.bool_value ());
+
+    if (obj)
+      py_object = object (handle<PyObject> (obj));
+    else
+      throw value_convert_exception ("unhandled scalar type");
+  }
+
+  static void
   octstring_to_pyobject (boost::python::object& py_object,
                          const std::string& str)
   {
@@ -231,6 +270,8 @@
         "Octave value `undefined'. Can not convert to a Python object");
     else if (octvalue.is_string ())
       octstring_to_pyobject (py_object, octvalue.string_value ());
+    else if (octvalue.is_scalar_type ())
+      octscalar_to_pyobject (py_object, octvalue);
     else if (octvalue.is_numeric_type () || octvalue.is_string ()
              || octvalue.is_cell () || octvalue.is_bool_type ())
       octvalue_to_pyarr (py_object, octvalue);
--- a/pycall.cc	Thu Jul 14 23:42:45 2016 -0700
+++ b/pycall.cc	Thu Jul 14 23:56:40 2016 -0700
@@ -204,20 +204,20 @@
 %!assert (ischar (pycall ("os.getcwd")))
 %!assert (isreal (pycall ("random.random")))
 %!assert (pycall ("math.exp", 3), exp (3))
-%!xtest assert (pycall ("math.trunc", pi), fix (pi))
+%!assert (pycall ("math.trunc", pi), fix (pi))
 %!assert (pycall ("math.sqrt", 2), sqrt (2))
-%!xtest assert (pycall ("cmath.sqrt", 2j), sqrt (2j))
+%!assert (pycall ("cmath.sqrt", 2j), sqrt (2j))
 %!assert (pycall ("int", 10.2), 10)
 
 ## Test argument type conversion of values into Python
 %!test
 %! pyexec ("def typename(x): return type(x).__name__");
-%!xtest assert (pycall ("typename", 0), "double")
-%!xtest assert (pycall ("typename", pi), "double")
-%!xtest assert (pycall ("typename", 2j), "complex")
-%!xtest assert (pycall ("typename", int32 (0)), "int")
-%!xtest assert (pycall ("typename", false), "bool")
-%!xtest assert (pycall ("typename", true), "bool")
+%!assert (pycall ("typename", 0), "float")
+%!assert (pycall ("typename", pi), "float")
+%!assert (pycall ("typename", 2j), "complex")
+%!assert (pycall ("typename", int32 (0)), "int")
+%!assert (pycall ("typename", false), "bool")
+%!assert (pycall ("typename", true), "bool")
 %!assert (pycall ("typename", "Hello world"), "str")
 %!assert (pycall ("typename", char ([1, 2, 3])), "str")
 
@@ -232,8 +232,8 @@
 
 %!test
 %! pyexec (["def pyfunc(x):\n" ...
-%!         "    if x.item((0,0)) is True:\n        return 30\n" ...
-%!         "    elif x.item((0,0)) is False:\n        return 20\n" ...
+%!         "    if x is True:\n        return 30\n" ...
+%!         "    elif x is False:\n        return 20\n" ...
 %!         "    else:\n        return 10"]);
 %! assert (pycall ("pyfunc", true), 30)
 %! assert (pycall ("pyfunc", false), 20)