Mercurial > pytave
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") |