changeset 408:f833e29b2c12

Simplify conversion where existing Python object argument expected (fixes issue #67) * __py_struct_from_dict__.cc (F__py_isinstance__, F__py_struct_from_dict__): Use pytave::pyobject_unwrap_object and simplify surrounding code. * oct-py-types.cc (pytave::extract_py_scalar_map): Raise Octave errors instead of throwing exceptions, reword error messages. * @pyobject/pyobject.m: Add %!error tests for struct conversion failure.
author Mike Miller <mtmiller@octave.org>
date Tue, 02 May 2017 10:06:14 -0700
parents 78448e4de20a
children b9b8790d1082
files @pyobject/pyobject.m __py_struct_from_dict__.cc oct-py-types.cc
diffstat 3 files changed, 14 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/@pyobject/pyobject.m	Mon May 01 09:15:40 2017 -0700
+++ b/@pyobject/pyobject.m	Tue May 02 10:06:14 2017 -0700
@@ -409,6 +409,11 @@
 %! c = struct (b);
 %! assert (c, a)
 
+%!error struct (pyeval ("{1:2, 3:4}"));
+%!error struct (pyobject ("this is not a dict"))
+%!error struct (pyobject ({1, 2, 3}))
+%!error struct (pyobject ())
+
 ## Octave fails to resolve function overloads via function handles
 %!xtest
 %! fn = @double;
--- a/__py_struct_from_dict__.cc	Mon May 01 09:15:40 2017 -0700
+++ b/__py_struct_from_dict__.cc	Tue May 02 10:06:14 2017 -0700
@@ -237,25 +237,9 @@
 
   pytave::py_init ();
 
-  try
-    {
-      // FIXME: PyObject *obj = look up stored pyobject reference (args(0));
-      boost::python::object arg;
-      pytave::octvalue_to_pyobj (arg, args(0));
-      PyObject *obj = arg.ptr ();
-
-      pytave::python_object type = pytave::py_find_type (typestr);
-      retval(0) = pytave::py_isinstance (obj, type);
-    }
-  catch (pytave::object_convert_exception const &)
-    {
-      error ("pyobject.isa: error in return value type conversion");
-    }
-  catch (boost::python::error_already_set const &)
-    {
-      std::string message = pytave::fetch_exception_message ();
-      error ("pyobject.isa: %s", message.c_str ());
-    }
+  pytave::python_object obj = pytave::pyobject_unwrap_object (args(0));
+  pytave::python_object type = pytave::py_find_type (typestr);
+  retval(0) = pytave::py_isinstance (obj, type);
 
   return retval;
 }
@@ -397,24 +381,8 @@
 
   pytave::py_init ();
 
-  try
-    {
-      // FIXME: PyObject *obj = look up stored pyobject reference (args(0));
-      boost::python::object arg;
-      pytave::octvalue_to_pyobj (arg, args(0));
-      PyObject *obj = arg.ptr ();
-
-      retval(0) = pytave::extract_py_scalar_map (obj);
-    }
-  catch (pytave::object_convert_exception const &)
-    {
-      error ("pyobject.struct: error in return value type conversion");
-    }
-  catch (boost::python::error_already_set const &)
-    {
-      std::string message = pytave::fetch_exception_message ();
-      error ("pyobject.struct: %s", message.c_str ());
-    }
+  pytave::python_object obj = pytave::pyobject_unwrap_object (args(0));
+  retval(0) = pytave::extract_py_scalar_map (obj);
 
   return retval;
 }
--- a/oct-py-types.cc	Mon May 01 09:15:40 2017 -0700
+++ b/oct-py-types.cc	Tue May 02 10:06:14 2017 -0700
@@ -335,10 +335,10 @@
   extract_py_scalar_map (PyObject *obj)
   {
     if (! obj)
-      throw object_convert_exception ("failed to extract map: null object");
+      error ("unable to convert to an Octave struct, invalid Python object");
 
     if (! PyDict_Check (obj))
-      throw object_convert_exception ("failed to extract map: wrong type");
+      error ("unable to convert to an Octave struct, must be a Python dict");
 
     octave_scalar_map map;
 
@@ -349,8 +349,8 @@
     while (PyDict_Next (obj, &pos, &py_key, &py_value))
       {
         if (! PyBytes_Check (py_key) && ! PyUnicode_Check (py_key))
-          throw object_convert_exception
-            ("failed to extract map: bad key type");
+          error ("unable to convert Python dict to Octave struct, "
+                 "all keys in the dict must be strings");
 
         std::string key = extract_py_str (py_key);
         octave_value value = wrap_pyobj_to_octvalue (py_value);