comparison @pyobject/subsref.m @ 369:540b36e797c8

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.
author Mike Miller <mtmiller@octave.org>
date Thu, 25 Aug 2016 23:20:02 -0700
parents 4d54fb68de71
children a8102b1a57a1
comparison
equal deleted inserted replaced
368:4d54fb68de71 369:540b36e797c8
33 33
34 34
35 function varargout = subsref (x, idx) 35 function varargout = subsref (x, idx)
36 36
37 t = idx(1); 37 t = idx(1);
38 switch t.type 38 switch (t.type)
39 case "()"
40 r = pycall (x, t.subs{:});
41
42 case "." 39 case "."
43 assert (ischar (t.subs)) 40 assert (ischar (t.subs))
44 r = pycall ("getattr", x, t.subs); 41 r = pycall ("getattr", x, t.subs);
42
43 case "()"
44 ## Determine the types and protocols that we are able to index into
45 x_is_callable = isa (x, "py.collections.Callable");
46 x_is_sequence = any (isa (x, {"py.collections.Sequence", ...
47 "py.array.array", "py.numpy.ndarray"}));
48
49 if (! (x_is_callable || x_is_sequence))
50 error ("subsref: cannot index Python object, not sequence or callable");
51 endif
52
53 if (x_is_sequence)
54 error ("subsref: slice indexing of Python objects not yet implemented");
55 endif
56
57 r = pycall (x, t.subs{:});
45 58
46 case "{}" 59 case "{}"
47 ## Determine the types and protocols that we are able to index into 60 ## Determine the types and protocols that we are able to index into
48 x_is_mapping = isa (x, "py.collections.Mapping"); 61 x_is_mapping = isa (x, "py.collections.Mapping");
49 x_is_sequence = any (isa (x, {"py.collections.Sequence", ... 62 x_is_sequence = any (isa (x, {"py.collections.Sequence", ...
52 if (! (x_is_mapping || x_is_sequence)) 65 if (! (x_is_mapping || x_is_sequence))
53 error ("subsref: cannot index Python object, not sequence or mapping"); 66 error ("subsref: cannot index Python object, not sequence or mapping");
54 endif 67 endif
55 68
56 ## Subtract one from index: do this for lists, arrays, numpy arrays, etc 69 ## Subtract one from index: do this for lists, arrays, numpy arrays, etc
57 for i = 1:length(t.subs) 70 for i = 1:length (t.subs)
58 j = t.subs{i}; 71 j = t.subs{i};
59 if (isindex (j) && isnumeric (j) && x_is_sequence) 72 if (isindex (j) && isnumeric (j) && x_is_sequence)
60 t.subs{i} = cast (j, class (sizemax ())) - 1; 73 t.subs{i} = cast (j, class (sizemax ())) - 1;
61 endif 74 endif
62 endfor 75 endfor
71 ind = t.subs{1}; 84 ind = t.subs{1};
72 else 85 else
73 ind = pycall ("tuple", t.subs); 86 ind = pycall ("tuple", t.subs);
74 endif 87 endif
75 88
76 gi = pycall ("getattr", x, "__getitem__"); # x.__getitem__
77 if (isempty (ind) && x_is_sequence) 89 if (isempty (ind) && x_is_sequence)
78 r = pyeval ("None"); 90 r = pyobject ();
79 elseif (isnumeric (ind) && length (ind) > 1) 91 elseif (isnumeric (ind) && length (ind) > 1)
80 r = {}; 92 r = {};
81 for k = 1:length (ind) 93 for k = 1:length (ind)
82 r(end+1) = pycall (gi, ind(k)); 94 r(end+1) = pycall ("operator.getitem", x, ind(k));
83 endfor 95 endfor
84 else 96 else
85 r = pycall (gi, ind); 97 r = pycall ("operator.getitem", x, ind);
86 endif 98 endif
87 99
88 otherwise 100 otherwise
89 t 101 t
90 error ("@pyobject/subsref: not implemented") 102 error ("@pyobject/subsref: not implemented")