Mercurial > pytave
changeset 322:2461b86cb8fb
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.
author | Mike Miller <mtmiller@octave.org> |
---|---|
date | Fri, 12 Aug 2016 00:45:39 -0700 |
parents | 3afd890fff6d |
children | a511d43e1fc0 |
files | @pyobject/subsref.m |
diffstat | 1 files changed, 26 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- 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 <cannot index Python object> +%! f = pyeval ("abs"); +%! f{1} + %!error <outputs must match> %! % multiple return values: too many outputs %! f = pyeval ("lambda: (1, 2)");