# HG changeset patch # User Mike Miller # Date 1470164652 25200 # Node ID 46d9b2972901c25c380921f94a97416aa14849ae # Parent b06df69f4b37ff18ff9765e86e8c09514b541cf2# Parent 4c4747646e12515b501e6c50b81400f1a0c383f8 Merged in macdonald/pytave (pull request #27) Make pyobject callable by users (to convert input) diff -r b06df69f4b37 -r 46d9b2972901 @pyobject/dummy.m --- a/@pyobject/dummy.m Sun Jul 31 12:29:15 2016 -0700 +++ b/@pyobject/dummy.m Tue Aug 02 12:04:12 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 = diff -r b06df69f4b37 -r 46d9b2972901 @pyobject/pyobject.m --- a/@pyobject/pyobject.m Sun Jul 31 12:29:15 2016 -0700 +++ b/@pyobject/pyobject.m Tue Aug 02 12:04:12 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) @@ -154,3 +190,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')")), "") + +%!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")) diff -r b06df69f4b37 -r 46d9b2972901 python_to_octave.cc --- a/python_to_octave.cc Sun Jul 31 12:29:15 2016 -0700 +++ b/python_to_octave.cc Tue Aug 02 12:04:12 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,