changeset 286:9e8faa439d1d

Merged in macdonald/pytave (pull request #35) use pyobject instead of accessing the InOct dict
author Mike Miller <mike@mtmxr.com>
date Tue, 02 Aug 2016 12:11:02 -0700
parents 46d9b2972901 (diff) 06a4b461b141 (current diff)
children ccd9fcaae5f8 f5282c87e5d5
files @pyobject/pyobject.m
diffstat 4 files changed, 55 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/@pyobject/dummy.m	Tue Aug 02 00:06:42 2016 -0700
+++ b/@pyobject/dummy.m	Tue Aug 02 12:11:02 2016 -0700
@@ -25,8 +25,10 @@
 ## Simple example:
 ## @example
 ## @group
-## pyexec ("g = 6")
-## g = pyobject.fromPythonVarName ("g");
+## g = pyobject (int32 (6))
+##   @result{} g = [pyobject ...]
+##
+##       6
 ##
 ## sort (methods (g))
 ##   @result{} ans =
--- a/@pyobject/pyobject.m	Tue Aug 02 00:06:42 2016 -0700
+++ b/@pyobject/pyobject.m	Tue Aug 02 12:11:02 2016 -0700
@@ -52,16 +52,52 @@
         pyvarname, pyvarname);
       pyexec (cmd);
       id = pyeval (["hex(id(" pyvarname "))"]);
-      x = pyobject (id);
+      x = pyobject (0, id);
     endfunction
   endmethods
 
 
   methods
-    function x = pyobject (id)
-      % warning: not intended for casual use: you must also insert
-      % the object into the Python `__InOct__` dict with key `id`.
-      x.id = id;
+    function obj = pyobject (x, id)
+      if (nargin == 0)
+        obj = pyeval ("None");
+        return
+      endif
+
+      if (nargin == 1)
+        ## Convert the input to a pyobject
+        if (isa (x, "pyobject"))
+          obj = x;
+        else
+          ## XXX: perhaps not the ideal implementation!
+          vars = pyeval ("__import__('__main__').__dict__");
+          ## this is vars{"_temp"} = x
+          idx = struct ("type", "{}", "subs", {{"_temp"}});
+          vars = subsasgn (vars, idx, x);
+          cmd = [ ...
+            "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" ...
+            "__InOct__[hex(id(_temp))] = _temp" ];
+          pyexec (cmd);
+          id = pyeval (["hex(id(_temp))"]);
+          obj = pyobject (0, id);
+        endif
+        return
+      endif
+
+      if (nargin == 2)
+        ## The actual constructor.  Nicer to split this off to static method
+        ## like `pyobject.new` but I don't know how to call from pycall.cc.
+        ## Warning: not intended for casual use: you must also insert the
+        ## object into the Python `__InOct__` dict with key `id`.
+        obj.id = id;
+        return
+      endif
+
+      error ("pyobject: unexpected input to the constructor")
     endfunction
 
     function delete (x)
@@ -155,3 +191,9 @@
 %!assert (char (pyeval ("[1, 2, 3, 4, 5]")), "[1, 2, 3, 4, 5]")
 %!assert (char (pyeval ("(1, 2, 3, 4, 5)")), "(1, 2, 3, 4, 5)")
 %!assert (char (pyeval ("__import__('sys')")), "<module 'sys' (built-in)>")
+
+%!assert (isa (pyobject (), "pyobject"))
+%!assert (isa (pyobject ("a string"), "pyobject"))
+%!assert (isa (pyobject (42.2), "pyobject"))
+%!assert (isa (pyobject (int32 (42)), "pyobject"))
+%!assert (isa (pyobject (pyobject ()), "pyobject"))
--- a/pycall.cc	Tue Aug 02 00:06:42 2016 -0700
+++ b/pycall.cc	Tue Aug 02 12:11:02 2016 -0700
@@ -203,11 +203,6 @@
           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);
-
       // Ensure reasonable "ans" behaviour, consistent with Python's "_".
       if (nargout > 0 || ! res.is_none ())
         {
@@ -242,6 +237,9 @@
 %!assert (pycall ("cmath.sqrt", 2j), sqrt (2j))
 %!assert (pycall ("int", 10.2), 10)
 %!assert (isa (pycall ("object"), "pyobject"))
+%!assert (isa (pycall ("dict"), "pyobject"))
+%!assert (isa (pycall ("list"), "pyobject"))
+%!assert (isa (pycall ("tuple"), "pyobject"))
 
 ## Test argument type conversion of values into Python
 %!test
--- a/python_to_octave.cc	Tue Aug 02 00:06:42 2016 -0700
+++ b/python_to_octave.cc	Tue Aug 02 12:11:02 2016 -0700
@@ -500,7 +500,7 @@
           main_namespace, main_namespace);
     main_namespace["__InOct__"][id] = py_object;
     // Create @pyobject
-    oct_value = feval ("pyobject", ovl (id), 1);
+    oct_value = feval ("pyobject", ovl (0, id), 2);
   }
 
   void pyobj_to_octvalue (octave_value& oct_value,