changeset 213:a54ab59c491d

merge genuinelucifer/cbm_pytave to macdonald/cbm_pytave
author Colin Macdonald <cbm@m.fsf.org>
date Thu, 26 May 2016 23:18:10 -0700
parents 3edceb6b7504 (current diff) dbdf80450a1d (diff)
children f48cad3e2c8e
files @pyobj/dummy.m @pyobj/pyobj.m @pyobject/pyobject.m
diffstat 5 files changed, 272 insertions(+), 272 deletions(-) [+]
line wrap: on
line diff
--- a/@pyobj/dummy.m	Thu May 26 12:43:56 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-%% Copyright (C) 2016 Colin B. Macdonald
-%%
-%% This file is part of PyTave.
-%%
-%% OctSymPy is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU General Public License as published
-%% by the Free Software Foundation; either version 3 of the License,
-%% or (at your option) any later version.
-%%
-%% This software is distributed in the hope that it will be useful,
-%% but WITHOUT ANY WARRANTY; without even the implied warranty
-%% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
-%% the GNU General Public License for more details.
-%%
-%% You should have received a copy of the GNU General Public
-%% License along with this software; see the file COPYING.
-%% If not, see <http://www.gnu.org/licenses/>.
-
-%% -*- texinfo -*-
-%% @documentencoding UTF-8
-%% @defmethod @@pyobj dummy (@var{x})
-%% Does nothing, stores doctests for now.
-%%
-%%
-%% Simple example:
-%% @example
-%% @group
-%% pyexec('g = 6')
-%% g = pyobj.fromPythonVarName('g');
-%%
-%% sort(whatmethods(g))
-%%   @result{} ans =
-%%     @{
-%%       [1,1] = bit_length
-%%       [1,2] = conjugate
-%%       [1,1] = denominator
-%%       [1,2] = imag
-%%       [1,3] = numerator
-%%       [1,4] = real
-%%      @}
-%%
-%% g.numerator
-%%   @result{} ans =  6
-%% g.denominator
-%%   @result{} ans =  1
-%% @end group
-%% @end example
-%%
-%%
-%% You can delete an object in Python and it will persist:
-%% @example
-%% @group
-%% pyexec('d = dict(one=1, two=2)')
-%% x = pyobj.fromPythonVarName('d')
-%%   @result{} x =
-%%       [PyObject id ...]
-%%       @{'two': 2, 'one': 1@}
-%%
-%% % oops, overwrote d in Python:
-%% pyexec('d = 42')
-%%
-%% % but have no fear, we still have a reference to it:
-%% x
-%%   @result{} x =
-%%       [PyObject id ...]
-%%       @{'two': 2, 'one': 1@}
-%% @end group
-%% @end example
-%%
-%% We can accesss ``callables'' (methods) of objects:
-%% @example
-%% @group
-%% x.keys()
-%%   @result{} ans =
-%%       @{
-%%         [1,1] = two
-%%         [1,2] = one
-%%       @}
-%% @end group
-%% @end example
-%%
-%% @code{pyeval} returns a @@pyobj for things it cannot convert to
-%% Octave-native objects:
-%% @example
-%% @group
-%% pyexec('import sys')
-%% sysmodule = pyeval('sys')
-%%   @result{} sysmodule =
-%%       [PyObject id ...]
-%%       <module 'sys' (built-in)>
-%% @end group
-%% @end example
-%%
-%% After you have the object, you can access its properties:
-%% @example
-%% @group
-%% sysmodule.version
-%%   @result{} ans = ...
-%% @end group
-%% @end example
-%%
-%%
-%% TODO: this should return a cell array with a double, a string,
-%% and an @@pyobj in it:
-%% @example
-%% @group
-%% pyeval('[42, "hello", sys]')         % doctest: +XFAIL
-%%   @result{} ans =
-%%       @{
-%%         [1,1] =  42
-%%         [1,2] = hello
-%%         [1,3] =
-%%           [PyObject id ...]
-%%           <module 'sys' (built-in)>
-%%       @}
-%% @end group
-%% @end example
-%%
-%% @seealso{pyobj}
-%% @end defmethod
-
-function dummy (x)
-
-end
--- a/@pyobj/pyobj.m	Thu May 26 12:43:56 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-%% Copyright (C) 2016 Colin B. Macdonald
-%%
-%% This file is part of PyTave.
-%%
-%% OctSymPy is free software; you can redistribute it and/or modify
-%% it under the terms of the GNU General Public License as published
-%% by the Free Software Foundation; either version 3 of the License,
-%% or (at your option) any later version.
-%%
-%% This software is distributed in the hope that it will be useful,
-%% but WITHOUT ANY WARRANTY; without even the implied warranty
-%% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
-%% the GNU General Public License for more details.
-%%
-%% You should have received a copy of the GNU General Public
-%% License along with this software; see the file COPYING.
-%% If not, see <http://www.gnu.org/licenses/>.
-
-%% -*- texinfo -*-
-%% @documentencoding UTF-8
-%% @defun  pyobj (@var{s})
-%% Wrap a Python object.
-%%
-%% TODO: where/how to document classdef classes?
-%%
-%% @seealso{pyexec, pyeval}
-%% @end defun
-
-classdef pyobj < handle
-  properties
-    id
-  end
-
-  methods(Static)
-    function x = fromPythonVarName(pyvarname)
-      % if @var{pyvarname} is a string, its assumed to be a variable
-      % name, e.g., previously created with pyexec.  This must exist
-      % at the time of construction but it can disappear later (we
-      % will keep track of the reference).
-      if (~ ischar(pyvarname))
-        error('pyobj: currently we only take variable names as input')
-      end
-      cmd = sprintf ([ ...
-        'if not ("__InOct__" in vars() or "__InOct__" in globals()):\n' ...
-        '  __InOct__ = dict()\n' ...
-        '__InOct__[hex(id(%s))] = %s' ], ...
-        pyvarname, pyvarname);
-      pyexec (cmd);
-      id = pyeval (['hex(id(' pyvarname '))']);
-      x = pyobj(id);
-    end
-  end
-
-
-  methods
-    function x = pyobj(id)
-      % warning: not intended for casual use: you must also insert
-      % the object into the Python `__InOct__` dict with key `id`.
-      x.id = id;
-    end
-
-    function delete(x)
-      % called on clear of the last reference---for subclasses of
-      % handle; not called at all for "value classes".
-      % FIXME: #46497 this is never called!
-      %save('proof_of_delete', 6, x.id)
-      disp ('delete')
-      % throws KeyError if it wasn't in there for some reason
-      cmd = sprintf ('__InOct__.pop("%s")', x.id);
-      pyexec (cmd);
-    end
-
-    function force_delete (x)
-      % Manual workaround for #46497: call right before @code{clear x}.  But
-      % be careful, @code{x} needs to be the last reference: don't do this:
-      % @example
-      % d = pyobj (...);
-      % d2 = d;
-      % force_delete (d)
-      % clear d
-      % d2
-      %   @print{} ... KeyError ...
-      % @end example
-      delete(x)
-    end
-
-    dummy (x)
-
-    function r = getid (x)
-      r = x.id;
-    end
-
-    function disp(x)
-      printf ('[PyObject id %s]\n', x.id);
-      disp (pyeval (sprintf ('str(__InOct__["%s"])', x.id)))
-    end
-
-    function s = whatclass(x)
-      s = pyeval (sprintf ('str(__InOct__["%s"].__class__)', x.id));
-    end
-
-    function lst = whatmethods(x)
-      % filter the output of `dir(x)`
-      % properties only:
-      % [a for a in dir(x) if not callable(getattr(x, a)) and not a.startswith("__")]
-      cmd = sprintf ( ...
-        '[a for a in dir(__InOct__["%s"]) if not a.startswith("__")]', ...
-        x.id);
-      lst = pyeval (cmd);
-    end
-
-    function r = subsref(x, idx)
-      s = '';
-      for i=1:length(idx)
-        t = idx(i);
-        switch t.type
-          case '()'
-            if ( ! isempty (t.subs))
-              t
-              error('not implemented: function calls with arguments')
-            end
-            s = sprintf ('%s()', s);
-          case '.'
-            assert(ischar(t.subs))
-            s = sprintf ('%s.%s', s, t.subs);
-          otherwise
-            t
-            error('not implemented')
-        end
-      end
-      r = pyeval (sprintf ('__InOct__["%s"]%s', x.id, s));
-    end
-
-    function vargout = help(x)
-      idx = struct('type', '.', 'subs', '__doc__');
-      s = subsref(x, idx);
-      if (nargout == 0)
-        disp(s)
-      else
-        vargout = {s};
-      end
-    end
-
-  end
-end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/@pyobject/dummy.m	Thu May 26 23:18:10 2016 -0700
@@ -0,0 +1,124 @@
+%% Copyright (C) 2016 Colin B. Macdonald
+%%
+%% This file is part of PyTave.
+%%
+%% OctSymPy is free software; you can redistribute it and/or modify
+%% it under the terms of the GNU General Public License as published
+%% by the Free Software Foundation; either version 3 of the License,
+%% or (at your option) any later version.
+%%
+%% This software is distributed in the hope that it will be useful,
+%% but WITHOUT ANY WARRANTY; without even the implied warranty
+%% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+%% the GNU General Public License for more details.
+%%
+%% You should have received a copy of the GNU General Public
+%% License along with this software; see the file COPYING.
+%% If not, see <http://www.gnu.org/licenses/>.
+
+%% -*- texinfo -*-
+%% @documentencoding UTF-8
+%% @defmethod @@pyobject dummy (@var{x})
+%% Does nothing, stores doctests for now.
+%%
+%%
+%% Simple example:
+%% @example
+%% @group
+%% pyexec('g = 6')
+%% g = pyobject.fromPythonVarName('g');
+%%
+%% sort(whatmethods(g))
+%%   @result{} ans =
+%%     @{
+%%       [1,1] = bit_length
+%%       [1,2] = conjugate
+%%       [1,1] = denominator
+%%       [1,2] = imag
+%%       [1,3] = numerator
+%%       [1,4] = real
+%%      @}
+%%
+%% g.numerator
+%%   @result{} ans =  6
+%% g.denominator
+%%   @result{} ans =  1
+%% @end group
+%% @end example
+%%
+%%
+%% You can delete an object in Python and it will persist:
+%% @example
+%% @group
+%% pyexec('d = dict(one=1, two=2)')
+%% x = pyobject.fromPythonVarName('d')
+%%   @result{} x =
+%%       [PyObject id ...]
+%%       @{'two': 2, 'one': 1@}
+%%
+%% % oops, overwrote d in Python:
+%% pyexec('d = 42')
+%%
+%% % but have no fear, we still have a reference to it:
+%% x
+%%   @result{} x =
+%%       [PyObject id ...]
+%%       @{'two': 2, 'one': 1@}
+%% @end group
+%% @end example
+%%
+%% We can accesss ``callables'' (methods) of objects:
+%% @example
+%% @group
+%% x.keys()
+%%   @result{} ans =
+%%       @{
+%%         [1,1] = two
+%%         [1,2] = one
+%%       @}
+%% @end group
+%% @end example
+%%
+%% @code{pyeval} returns a @@pyobject for things it cannot convert to
+%% Octave-native objects:
+%% @example
+%% @group
+%% pyexec('import sys')
+%% sysmodule = pyeval('sys')
+%%   @result{} sysmodule =
+%%       [PyObject id ...]
+%%       <module 'sys' (built-in)>
+%% @end group
+%% @end example
+%%
+%% After you have the object, you can access its properties:
+%% @example
+%% @group
+%% sysmodule.version
+%%   @result{} ans = ...
+%% @end group
+%% @end example
+%%
+%%
+%% TODO: this should return a cell array with a double, a string,
+%% and an @@pyobject in it:
+%% @example
+%% @group
+%% pyeval('[42, "hello", sys]')         % doctest: +XFAIL
+%%   @result{} ans =
+%%       @{
+%%         [1,1] =  42
+%%         [1,2] = hello
+%%         [1,3] =
+%%           [PyObject id ...]
+%%           <module 'sys' (built-in)>
+%%       @}
+%% @end group
+%% @end example
+%%
+%% @seealso{pyobject}
+%% @end defmethod
+
+function dummy (x)
+
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/@pyobject/pyobject.m	Thu May 26 23:18:10 2016 -0700
@@ -0,0 +1,145 @@
+%% Copyright (C) 2016 Colin B. Macdonald
+%%
+%% This file is part of PyTave.
+%%
+%% OctSymPy is free software; you can redistribute it and/or modify
+%% it under the terms of the GNU General Public License as published
+%% by the Free Software Foundation; either version 3 of the License,
+%% or (at your option) any later version.
+%%
+%% This software is distributed in the hope that it will be useful,
+%% but WITHOUT ANY WARRANTY; without even the implied warranty
+%% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+%% the GNU General Public License for more details.
+%%
+%% You should have received a copy of the GNU General Public
+%% License along with this software; see the file COPYING.
+%% If not, see <http://www.gnu.org/licenses/>.
+
+%% -*- texinfo -*-
+%% @documentencoding UTF-8
+%% @defun  pyobject (@var{s})
+%% Wrap a Python object.
+%%
+%% TODO: where/how to document classdef classes?
+%%
+%% @seealso{pyexec, pyeval}
+%% @end defun
+
+classdef pyobject < handle
+  properties
+    id
+  end
+
+  methods(Static)
+    function x = fromPythonVarName(pyvarname)
+      % if @var{pyvarname} is a string, its assumed to be a variable
+      % name, e.g., previously created with pyexec.  This must exist
+      % at the time of construction but it can disappear later (we
+      % will keep track of the reference).
+      if (~ ischar(pyvarname))
+        error('pyobject: currently we only take variable names as input')
+      end
+      cmd = sprintf ([ ...
+        'if not ("__InOct__" in vars() or "__InOct__" in globals()):\n' ...
+        '  __InOct__ = dict()\n' ...
+        '__InOct__[hex(id(%s))] = %s' ], ...
+        pyvarname, pyvarname);
+      pyexec (cmd);
+      id = pyeval (['hex(id(' pyvarname '))']);
+      x = pyobject(id);
+    end
+  end
+
+
+  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;
+    end
+
+    function delete(x)
+      % called on clear of the last reference---for subclasses of
+      % handle; not called at all for "value classes".
+      % FIXME: #46497 this is never called!
+      %save('proof_of_delete', 6, x.id)
+      disp ('delete')
+      % throws KeyError if it wasn't in there for some reason
+      cmd = sprintf ('__InOct__.pop("%s")', x.id);
+      pyexec (cmd);
+    end
+
+    function force_delete (x)
+      % Manual workaround for #46497: call right before @code{clear x}.  But
+      % be careful, @code{x} needs to be the last reference: don't do this:
+      % @example
+      % d = pyobject (...);
+      % d2 = d;
+      % force_delete (d)
+      % clear d
+      % d2
+      %   @print{} ... KeyError ...
+      % @end example
+      delete(x)
+    end
+
+    dummy (x)
+
+    function r = getid (x)
+      r = x.id;
+    end
+
+    function disp(x)
+      printf ('[PyObject id %s]\n', x.id);
+      disp (pyeval (sprintf ('str(__InOct__["%s"])', x.id)))
+    end
+
+    function s = whatclass(x)
+      s = pyeval (sprintf ('str(__InOct__["%s"].__class__)', x.id));
+    end
+
+    function lst = whatmethods(x)
+      % filter the output of `dir(x)`
+      % properties only:
+      % [a for a in dir(x) if not callable(getattr(x, a)) and not a.startswith("__")]
+      cmd = sprintf ( ...
+        '[a for a in dir(__InOct__["%s"]) if not a.startswith("__")]', ...
+        x.id);
+      lst = pyeval (cmd);
+    end
+
+    function r = subsref(x, idx)
+      s = '';
+      for i=1:length(idx)
+        t = idx(i);
+        switch t.type
+          case '()'
+            if ( ! isempty (t.subs))
+              t
+              error('not implemented: function calls with arguments')
+            end
+            s = sprintf ('%s()', s);
+          case '.'
+            assert(ischar(t.subs))
+            s = sprintf ('%s.%s', s, t.subs);
+          otherwise
+            t
+            error('not implemented')
+        end
+      end
+      r = pyeval (sprintf ('__InOct__["%s"]%s', x.id, s));
+    end
+
+    function vargout = help(x)
+      idx = struct('type', '.', 'subs', '__doc__');
+      s = subsref(x, idx);
+      if (nargout == 0)
+        disp(s)
+      else
+        vargout = {s};
+      end
+    end
+
+  end
+end
--- a/pyeval.cc	Thu May 26 12:43:56 2016 -0700
+++ b/pyeval.cc	Thu May 26 23:18:10 2016 -0700
@@ -90,14 +90,14 @@
     }
   catch (pytave::object_convert_exception const &)
     {
-      printf ("pyeval: could not convert return value to Octave-native object, making pyobj...\n");
+      printf ("pyeval: could not convert return value to Octave-native object, making pyobject...\n");
       // 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",
             main_namespace, main_namespace);
       main_namespace["__InOct__"][id] = res;
-      // Create @pyobj
-      retval = feval ("pyobj", ovl (id), 1);
+      // Create @pyobject
+      retval = feval ("pyobject", ovl (id), 1);
     }
   catch (error_already_set const &)
     {