changeset 249:b1f874a68e0f

Add pyobject fieldnames and struct methods (fixes issue #33) * @pyobject/fieldnames.m: New method to return public data properties of a Python object. * @pyobject/struct.m: New method to construct a struct with values copied from the public properties of a Python object.
author Mike Miller <mtmiller@octave.org>
date Wed, 27 Jul 2016 19:18:54 -0700
parents 2e4c9ce0c83c
children a4a2c214415e
files @pyobject/fieldnames.m @pyobject/struct.m
diffstat 2 files changed, 150 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/@pyobject/fieldnames.m	Wed Jul 27 19:18:54 2016 -0700
@@ -0,0 +1,79 @@
+## Copyright (C) 2016 Mike Miller
+##
+## This file is part of Pytave
+##
+## Pytave 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 fieldnames (@var{x})
+## List the properties of a Python object.
+##
+## Returns a cell array of strings containing the names of the properties
+## of @var{x}.
+##
+## Example:
+## @example
+## @group
+## pyexec ("import sys")
+## sys = pyeval ("sys");
+## fieldnames (sys)
+##   @result{} ans =
+##     @{
+##       [1,1] = ...
+##       [2,1] = ...
+##        ...  = path
+##        ...  = version
+##        ...
+##     @}
+## @end group
+## @end example
+##
+## @seealso{fieldnames, @@pyobject/methods}
+## @end defmethod
+
+
+function names = fieldnames (x)
+
+  cmd = sprintf (["[a for x in (__InOct__['%s'],) for a in dir(x) " ...
+                  " if not callable(getattr(x, a))" ...
+                  " and not isinstance(getattr(x, a), __import__('types').ModuleType)" ...
+                  " and not a.startswith('_')]"],
+                 getid (x));
+
+  # FIXME: may need to convert from Python list to Octave cell array
+  names = pyeval (cmd);
+  names = names(:);
+
+endfunction
+
+
+%!test
+%! sys = pycall ("__import__", "sys");
+%! lst = fieldnames (sys);
+%! assert (iscell (lst))
+%! assert (length (lst) >= 32)
+%! assert (any (strcmp (lst, "path")))
+%! assert (any (strcmp (lst, "prefix")))
+%! assert (any (strcmp (lst, "stderr")))
+%! assert (any (strcmp (lst, "stdin")))
+%! assert (any (strcmp (lst, "stdout")))
+%! assert (any (strcmp (lst, "version")))
+
+%!test
+%! lst = fieldnames (pyeval ("__builtins__"));
+%! assert (any (strcmp (lst, "False")))
+%! assert (any (strcmp (lst, "None")))
+%! assert (any (strcmp (lst, "True")))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/@pyobject/struct.m	Wed Jul 27 19:18:54 2016 -0700
@@ -0,0 +1,71 @@
+## Copyright (C) 2016 Mike Miller
+##
+## This file is part of Pytave
+##
+## Pytave 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 struct (@var{x})
+## Convert a Python object to an Octave struct containing copies of its
+## public properties.
+##
+## Example:
+## @example
+## @group
+## os = pycall ("__import__", "os");
+## struct (os)
+##   @result{} scalar structure containing the fields:
+##       ...
+##       ...
+##       environ = ...
+##       name = ...
+##       ...
+## @end group
+## @end example
+##
+## @seealso{struct, @@pyobject/fieldnames}
+## @end defmethod
+
+
+function retval = struct (x)
+
+  retval = struct ();
+  names = fieldnames (x);
+  for i = 1:numel (names)
+    retval = setfield (retval, names{i}, pycall ("getattr", x, names{i}));
+  endfor
+
+endfunction
+
+
+%!test
+%! os = pycall ("__import__", "os");
+%! rv = struct (os);
+%! assert (isstruct (rv))
+%! assert (numfields (rv) >= 10)
+%! assert (fieldnames (rv), fieldnames (os))
+%! assert (isfield (rv, "curdir"))
+%! assert (isfield (rv, "devnull"))
+%! assert (isfield (rv, "environ"))
+%! assert (isfield (rv, "name"))
+%! assert (isfield (rv, "pathsep"))
+%! assert (isfield (rv, "sep"))
+
+%!test
+%! rv = struct (pyeval ("__builtins__"));
+%! assert (rv.False, false)
+%! assert (rv.True, true)
+%! assert (isequal (rv.None, pyeval ("None")))