# HG changeset patch # User Mike Miller # Date 1470264099 25200 # Node ID a0dc81daf5537859a9f25a4d810c035047257aeb # Parent ccd9fcaae5f8bec7b5103e26502ea1e91a6a2d63# Parent f2b4576879a6a368bf753d8c61e413c776df17fc Merged in genuinelucifer/pytave_main (pull request #31) Edit test and functions to adapt to lists, dicts being pyobjects diff -r ccd9fcaae5f8 -r a0dc81daf553 @pyobject/fieldnames.m --- a/@pyobject/fieldnames.m Tue Aug 02 12:28:07 2016 -0700 +++ b/@pyobject/fieldnames.m Wed Aug 03 15:41:39 2016 -0700 @@ -52,8 +52,10 @@ " and not isinstance(getattr(x, a), __import__('types').ModuleType)" ... " and not a.startswith('_')]"]); - # FIXME: may need to convert from Python list to Octave cell array - names = pycall (cmd, x); + names_obj = pycall (cmd, x); + len = length (names_obj); + idx = struct ("type", "{}", "subs", {{1:len}}); + [names{1:len}] = subsref (names_obj, idx); names = names(:); endfunction diff -r ccd9fcaae5f8 -r a0dc81daf553 @pyobject/methods.m --- a/@pyobject/methods.m Tue Aug 02 12:28:07 2016 -0700 +++ b/@pyobject/methods.m Wed Aug 03 15:41:39 2016 -0700 @@ -71,8 +71,10 @@ cmd = pyeval (["lambda x: [a for a in dir(x)" ... " if callable(getattr(x, a)) and not a.startswith('_')]"]); - # FIXME: may need to convert from Python list to Octave cell array - mtds_list = pycall (cmd, x) + mtds_list_obj = pycall (cmd, x); + len = length (mtds_list_obj); + idx = struct ("type", "{}", "subs", {{1:len}}); + [mtds_list{1:len}] = subsref (mtds_list_obj, idx); if (nargout == 0) ## FIXME: should this be available as @pyobject/ismodule.m ? diff -r ccd9fcaae5f8 -r a0dc81daf553 @pyobject/subsref.m --- a/@pyobject/subsref.m Tue Aug 02 12:28:07 2016 -0700 +++ b/@pyobject/subsref.m Wed Aug 03 15:41:39 2016 -0700 @@ -57,7 +57,14 @@ endif endfor - if (isscalar (t.subs)) + if (ischar (t.subs{1}) && strcmp (t.subs{1}, ":")) + is_map = pyeval ("lambda x: isinstance(x, collections.Mapping)"); + if (pycall (is_map, x)) + ind = ":"; + else + ind = int32 ([1:length(x)] - 1); + endif + elseif (isscalar (t.subs)) ind = t.subs{1}; else ## XXX: after #26, #27, I think its just: @@ -70,8 +77,16 @@ pyexec ("_temp = tuple(_temp[0])"); ind = pyobject.fromPythonVarName ("_temp"); endif + gi = pycall ("getattr", x, "__getitem__"); # x.__getitem__ - r = pycall (gi, ind); + if (isnumeric (ind) && length (ind) > 1) + r = {}; + for k = 1:length (ind) + r(end+1) = pycall (gi, ind(k)); + endfor + else + r = pycall (gi, ind); + endif otherwise t @@ -92,7 +107,7 @@ elseif (nargout >= 2) assert (length (r) == nargout, ... "pyobject/subsref: number of outputs must match") - [varargout{1:nargout}] = r{1:nargout}; + [varargout{1:nargout}] = subsref (r, struct ("type", "{}", "subs", {{1:nargout}})); endif endfunction @@ -104,11 +119,11 @@ %! assert (L{1}, 10) %! assert (L{2}, 20) -%!xtest +%!test %! % list indexing, slice %! pyexec ("L = [10, 20, [30, 40]]") %! L = pyobject.fromPythonVarName ("L"); -%! L2 = L{:}; +%! [L2{1:length(L)}] = L{:}; %! assert (L2{1}, 10) %! assert (L2{2}, 20) %! assert (L2{3}{1}, 30) @@ -227,6 +242,12 @@ %! f (); %! assert (length (ans) == 3) +%!test +%! % ensure None is returned if nargout > 0 +%! L = pyeval ("[1, None, 3]"); +%! a = L{2}; +%! assert (char (a), "None") + %!error %! % multiple return values: too many outputs %! f = pyeval ("lambda: (1, 2)");