# HG changeset patch # User Mike Miller # Date 1472192402 25200 # Node ID 540b36e797c897dcc6601219287ea30381e90040 # Parent 4d54fb68de714b112612bed122f9999e25e9c236 Reduce number of function calls, clean up formatting in subasgn and subsref * @pyobject/subsasgn.m: Reduce number of pycalls. * @pyobject/subsref.m: Reduce number of pycalls. Clean up code formatting. Add type checks for '()' indexing, explicit error message about slice indexing. diff -r 4d54fb68de71 -r 540b36e797c8 @pyobject/subsasgn.m --- a/@pyobject/subsasgn.m Thu Aug 25 16:27:46 2016 -0700 +++ b/@pyobject/subsasgn.m Thu Aug 25 23:20:02 2016 -0700 @@ -65,8 +65,7 @@ ind = pycall ("tuple", idx.subs); endif - xsi = pycall ("getattr", x, "__setitem__"); # x.__setitem__ - pycall (xsi, ind, rhs); + pycall ("operator.setitem", x, ind, rhs); r = x; otherwise diff -r 4d54fb68de71 -r 540b36e797c8 @pyobject/subsref.m --- a/@pyobject/subsref.m Thu Aug 25 16:27:46 2016 -0700 +++ b/@pyobject/subsref.m Thu Aug 25 23:20:02 2016 -0700 @@ -35,14 +35,27 @@ function varargout = subsref (x, idx) t = idx(1); - switch t.type - case "()" - r = pycall (x, t.subs{:}); - + switch (t.type) case "." assert (ischar (t.subs)) r = pycall ("getattr", x, t.subs); + case "()" + ## Determine the types and protocols that we are able to index into + x_is_callable = isa (x, "py.collections.Callable"); + x_is_sequence = any (isa (x, {"py.collections.Sequence", ... + "py.array.array", "py.numpy.ndarray"})); + + if (! (x_is_callable || x_is_sequence)) + error ("subsref: cannot index Python object, not sequence or callable"); + endif + + if (x_is_sequence) + error ("subsref: slice indexing of Python objects not yet implemented"); + endif + + r = pycall (x, t.subs{:}); + case "{}" ## Determine the types and protocols that we are able to index into x_is_mapping = isa (x, "py.collections.Mapping"); @@ -54,7 +67,7 @@ endif ## Subtract one from index: do this for lists, arrays, numpy arrays, etc - for i = 1:length(t.subs) + for i = 1:length (t.subs) j = t.subs{i}; if (isindex (j) && isnumeric (j) && x_is_sequence) t.subs{i} = cast (j, class (sizemax ())) - 1; @@ -73,16 +86,15 @@ ind = pycall ("tuple", t.subs); endif - gi = pycall ("getattr", x, "__getitem__"); # x.__getitem__ if (isempty (ind) && x_is_sequence) - r = pyeval ("None"); + r = pyobject (); elseif (isnumeric (ind) && length (ind) > 1) r = {}; for k = 1:length (ind) - r(end+1) = pycall (gi, ind(k)); + r(end+1) = pycall ("operator.getitem", x, ind(k)); endfor else - r = pycall (gi, ind); + r = pycall ("operator.getitem", x, ind); endif otherwise