changeset 219:8455e5e52c8a

Add Python [] indexing via {} indexing of @pyobject Octave doesn't have [] indexing. Its possible we will later want to use () indexing for lists, but for now {} to [] is easier to implement. Note we also substract one from integer indexing because Python indexes from 0 whereas Python indexes from 1. This induces certain bugs: we add an xtest for a bug on dicts. In addition to integer indexing, we also support strings, useful for string keys in dicts (tested). We support the special case of ":" which is mapped onto the same Python notation (tested). Multidimensional indexing is supported and is tested with NumPy arrays. *pyobject/pyobject.m: implement some forms of {} indexing.
author Colin Macdonald <cbm@m.fsf.org>
date Sun, 05 Jun 2016 22:38:56 -0700
parents 02da92723889
children 31e0ef489b64
files @pyobject/pyobject.m
diffstat 1 files changed, 70 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/@pyobject/pyobject.m	Sun Jun 05 22:29:34 2016 -0700
+++ b/@pyobject/pyobject.m	Sun Jun 05 22:38:56 2016 -0700
@@ -131,6 +131,23 @@
           case '.'
             assert (ischar (t.subs))
             s = sprintf ('%s.%s', s, t.subs);
+          case '{}'
+            subsstrs = {};
+            for j = 1:length (t.subs)
+	      thissub = t.subs{j};
+              if (ischar (thissub) && strcmp (thissub, ':'))
+                subsstrs{j} = ':';
+              elseif (ischar (thissub))
+                subsstrs{j} = ['"' thissub '"'];
+              elseif (isnumeric (thissub) && isscalar (thissub))
+                % note: python indexed from 0
+                subsstrs{j} = num2str (thissub - 1);
+              else
+                thissub
+                error ('@pyobject/subsref: subs not supported')
+              end
+            end
+            s = [s '[' strjoin(subsstrs, ', ') ']'];
           otherwise
             t
             error('not implemented')
@@ -151,3 +168,56 @@
 
   end
 end
+
+
+%!test
+%! % list indexing
+%! pyexec ('L = [10, 20]')
+%! L = pyobject.fromPythonVarName ('L');
+%! assert (L{1}, 10)
+%! assert (L{2}, 20)
+
+%!test
+%! % list indexing
+%! pyexec ('L = [10, 20, [30, 40]]')
+%! L = pyobject.fromPythonVarName ('L');
+%! L2 = L{:};
+%! assert (L2{1}, 10)
+%! assert (L2{2}, 20)
+%! assert (L2{3}{1}, 30)
+%! assert (L2{3}{2}, 40)
+
+%!test
+%! % list indexing, nested list
+%! pyexec ('L = [1, 2, [10, 11, 12]]')
+%! L = pyobject.fromPythonVarName ('L');
+%! assert (L{2}, 2)
+%! assert (L{3}{1}, 10)
+%! assert (L{3}{3}, 12)
+
+%!test
+%! % 2D array indexing
+%! pyexec ('import numpy')
+%! pyexec ('A = numpy.array([[1, 2], [3, 4]])')
+%! A = pyobject.fromPythonVarName ('A');
+%! assert (A{1, 1}, 1)
+%! assert (A{2, 1}, 3)
+%! assert (A{1, 2}, 2)
+
+%!test
+%! % dict: str key access
+%! pyexec ('d = {"one":1, 5:5, 6:6}')
+%! d = pyobject.fromPythonVarName ('d');
+%! assert (d{'one'}, 1)
+
+%!test
+%! % dict: integer key access
+%! pyexec ('d = {5:42, 6:42}')
+%! d = pyobject.fromPythonVarName ('d');
+%! assert (d{6}, 42)
+
+%!xtest
+%! % dict: integer key is broken because
+%! pyexec ('d = {5:40, 6:42}')
+%! d = pyobject.fromPythonVarName ('d');
+%! assert (d{6}, 42)