# HG changeset patch # User Mike Miller # Date 1470987939 25200 # Node ID 2461b86cb8fb49690605062a52e0d41e685ea66b # Parent 3afd890fff6de806251a5a66e3bd915c7d8187e1 pyobject.subsref: support indexing into Python array objects * @pyobject/subsref.m: Add support for sequence indexing into Python array objects. Clean up detection of Python types and protocols that can be indexed. Add %!tests for array indexing and improved type detection. diff -r 3afd890fff6d -r 2461b86cb8fb @pyobject/subsref.m --- a/@pyobject/subsref.m Thu Aug 11 22:35:19 2016 -0700 +++ b/@pyobject/subsref.m Fri Aug 12 00:45:39 2016 -0700 @@ -44,22 +44,28 @@ r = pycall ("getattr", x, t.subs); case "{}" - ## Subtract one from index: do this for lists, numpy arrays, etc - pyexec ("import collections") - pyexec ("import numpy") - x_is_list = pycall (pyeval ( - "lambda x: isinstance(x, (collections.Sequence, numpy.ndarray))"), - x); + ## Determine the types and protocols that we are able to index into + x_is_mapping = pycall (pyeval ( + "lambda x: isinstance(x, __import__('collections').Mapping)"), x); + x_is_sequence = pycall (pyeval ( + ["lambda x: isinstance(x, (__import__('collections').Sequence, " ... + "__import__('array').array, " ... + "__import__('numpy').ndarray))"]), x); + + if (! (x_is_mapping || x_is_sequence)) + error ("subsref: cannot index Python object, not sequence or mapping"); + endif + + ## Subtract one from index: do this for lists, arrays, numpy arrays, etc for i = 1:length(t.subs) j = t.subs{i}; - if (isindex (j) && isnumeric (j) && x_is_list) + if (isindex (j) && isnumeric (j) && x_is_sequence) t.subs{i} = cast (j, class (sizemax ())) - 1; endif endfor if (ischar (t.subs{1}) && strcmp (t.subs{1}, ":")) - is_map = pyeval ("lambda x: isinstance(x, collections.Mapping)"); - if (pycall (is_map, x)) + if (x_is_mapping) ind = ":"; else ind = int32 ([1:length(x)] - 1); @@ -141,6 +147,13 @@ %! assert (A{2, 1}, 3) %! assert (A{1, 2}, 2) +## Test element indexing on array.array types +%!test +%! a = pycall ("array.array", "d", {11, 12, 13, 14}); +%! assert (a{1}, 11) +%! assert (a{2}, 12) +%! assert (a{end}, 14) + %!test %! % dict: str key access %! d = pyeval ("{'one':1, 5:5, 6:6}"); @@ -238,6 +251,10 @@ %! a = L{2}; %! assert (char (a), "None") +%!error +%! f = pyeval ("abs"); +%! f{1} + %!error %! % multiple return values: too many outputs %! f = pyeval ("lambda: (1, 2)");