changeset 235:bbf0b7a4e117

Return pyobject from pycall too, similar to pyeval (fixes issue #28) * pycall.cc: Add the same logic as pyeval to convert return value to pyobject in case of object_convert_exception. Add a test to verify. * pyeval.cc: Add a similar test to verify pyobject is returned.
author Abhinav Tripathi <genuinelucifer@gmail.com>
date Thu, 21 Jul 2016 00:49:37 -0700
parents 237b71aaf6e7
children 89a1f5a82467
files pycall.cc pyeval.cc
diffstat 2 files changed, 21 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/pycall.cc	Wed Jul 20 14:24:09 2016 -0700
+++ b/pycall.cc	Thu Jul 21 00:49:37 2016 -0700
@@ -60,6 +60,8 @@
 @end deftypefn")
 {
   octave_value_list retval;
+  object res;
+  std::string id;
 
   int nargin = args.length ();
 
@@ -85,6 +87,7 @@
   _import_array ();
 
   object main_module = import ("__main__");
+  object main_namespace = main_module.attr ("__dict__");
 #if PY_VERSION_HEX >= 0x03000000
   object builtins_module = import ("builtins");
 #else
@@ -135,8 +138,6 @@
           pyargs.push_back (arg);
         }
 
-      object res;
-
       switch (nargin - 1)
         {
         case 0:
@@ -185,6 +186,11 @@
           break;
         }
 
+      object hex_function = builtins_module.attr ("hex");
+      object id_function = builtins_module.attr ("id");
+      object idtmp = hex_function (id_function (res));
+      id = extract<std::string> (idtmp);
+
       if (! res.is_none ())
         {
           octave_value val;
@@ -194,7 +200,16 @@
     }
   catch (pytave::object_convert_exception const &)
     {
-      error ("pycall: error in return value type conversion");
+      // Ensure we have a __InOct__ dict, and then put `res` into it
+      exec ("if not (\"__InOct__\" in vars() or \"__InOct__\" in globals()):\n"
+            "    __InOct__ = dict()\n"
+            "    # FIXME: make it accessible elsewhere?\n"
+            "    import __main__\n"
+            "    __main__.__InOct__ = __InOct__\n",
+            main_namespace, main_namespace);
+      main_namespace["__InOct__"][id] = res;
+      // Create @pyobject
+      retval = feval ("pyobject", ovl (id), 1);
     }
   catch (pytave::value_convert_exception const &)
     {
@@ -217,6 +232,7 @@
 %!assert (pycall ("math.sqrt", 2), sqrt (2))
 %!assert (pycall ("cmath.sqrt", 2j), sqrt (2j))
 %!assert (pycall ("int", 10.2), 10)
+%!assert (isa (pycall ("object"), "pyobject"))
 
 ## Test argument type conversion of values into Python
 %!test
--- a/pyeval.cc	Wed Jul 20 14:24:09 2016 -0700
+++ b/pyeval.cc	Thu Jul 21 00:49:37 2016 -0700
@@ -140,6 +140,8 @@
 %!assert (class (pyeval ("True")), "logical")
 %!assert (class (pyeval ("False")), "logical")
 
+%!assert (isa (pyeval ("object()"), "pyobject"))
+
 ## FIXME: these will change when dict, list, and tuple are not converted
 %!assert (pyeval ("{'x': 1, 'y': 2}"), struct ("x", 1, "y", 2))
 %!assert (pyeval ("[1, 2, 3]"), {1, 2, 3})