Thanks!  Problem solved.  Works fine with overloaded __setitem__&#39;s too.<br><br>Neil Birkbeck<br><br><div class="gmail_quote">On Sat, Apr 18, 2009 at 9:56 AM, Phil Thompson <span dir="ltr">&lt;<a href="mailto:phil@riverbankcomputing.com">phil@riverbankcomputing.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">On Thu, 16 Apr 2009 12:26:17 -0600 (MDT), Neil Birkbeck<br>
&lt;<a href="mailto:birkbeck@cs.ualberta.ca">birkbeck@cs.ualberta.ca</a>&gt; wrote:<br>
&gt; In older versions of sip (4.7.3), I have used __setitem__, __getitem__ to<br>
<br>
&gt; access/set elements from multidimensional quantities of a wrapped c++<br>
&gt; object that uses operator()(int,int).  For example, the following sip<br>
code<br>
&gt; used to work fine<br>
&gt;<br>
&gt; class A {<br>
&gt;  int operator()(int x,int y) const;<br>
&gt;<br>
&gt;  int __getitem__(int x,int y) const;<br>
&gt; %MethodCode<br>
&gt; ...<br>
&gt; %End<br>
&gt;<br>
&gt;  void __setitem__(int x,int y, int val) const;<br>
&gt; %MethodCode<br>
&gt; ...<br>
&gt; %End<br>
&gt; };<br>
&gt;<br>
&gt;&gt;From the ChangeLog this feature seemed to have been removed (in a related<br>
<br>
&gt; mailing list post, it was reported that the above usage was a bug<br>
&gt;<br>
<a href="http://article.gmane.org/gmane.comp.python.pyqt-pykde/12342/match=sip+__setitem__" target="_blank">http://article.gmane.org/gmane.comp.python.pyqt-pykde/12342/match=sip+__setitem__</a>).<br>
&gt;<br>
&gt; With the new checking (sip 4.7.9, possibly earlier), the above code will<br>
&gt; now give an error (e.g., sip: A.sip:18: Incorrect number of arguments to<br>
&gt; Python slot).  The previous mailing list post<br>
&gt; (<a href="http://thread.gmane.org/gmane.comp.python.pyqt-pykde/12342" target="_blank">http://thread.gmane.org/gmane.comp.python.pyqt-pykde/12342</a>) suggested to<br>
<br>
&gt; either not use __setitem__/__getitem__ for this purpose or to use a<br>
tuple.<br>
&gt;<br>
&gt; I updated my code and the tuples work fine for __getitem__, but I cannot<br>
&gt; seem to get the tuple to work for __setitem__.<br>
&gt;<br>
&gt; For example,<br>
&gt;<br>
&gt; A.sip:<br>
&gt;<br>
&gt; class A {<br>
&gt;  int __getitem(int x,int y);<br>
&gt; %MethodCode<br>
&gt;  //This is just a dummy, actually parse the tuple and extract indices...<br>
&gt; %End<br>
&gt;<br>
&gt;  void __setitem__(SIP_PYOBJECT, SIP_PYOBJECT);<br>
&gt; %MethodCode<br>
&gt;   //Do something here....<br>
&gt; %End<br>
&gt; };<br>
&gt;<br>
&gt; Python test:<br>
&gt; from A import A<br>
&gt; a = A(10,10)<br>
&gt; # Getting works fine, no error parsing arguments<br>
&gt; b = a[0,0]<br>
&gt; b = a[0]<br>
&gt;<br>
&gt; # Setting works with anything but tuple<br>
&gt; a[0] = 1 # Works fine<br>
&gt; a[[1,2]] = 1 # Also works, but is not really a desired syntax<br>
&gt; a[0:5] = 1   # Works, would check for this when parsing args.<br>
&gt; a[(0,1)] = 1 # Error: &quot;TypeError: too many arguments to A.__setitem__(),<br>
2<br>
&gt; at most expected&quot;<br>
&gt; a[0,1] = 1 #  Same error<br>
&gt; tup = (0,1)<br>
&gt; a[tup] = 1 # Same error<br>
&gt;<br>
&gt; The tuple always gets unpacked into more than one argument for<br>
__setitem__<br>
&gt; and causes the TypeError, which happens before any of the sip %MethodCode<br>
<br>
&gt; can be called.<br>
&gt;<br>
&gt; Looking at the generated code for the __setitem__, the parsing of args<br>
&gt; looks something like:<br>
&gt; sipParseArgs(&amp;sipArgsParsed,sipArgs,&quot;P0P0&quot;,&amp;a0,&amp;a1)<br>
&gt;<br>
&gt; On the other hand, the parsing of args for __getitem__ seems to work due<br>
&gt; to the single arg format of &quot;1P0&quot;.  Manually editing the generated code<br>
to<br>
&gt; return the args packed into a single tuple (including the set value) like<br>
<br>
&gt; __getitem__ works but is not a satisfying solution.<br>
&gt;<br>
&gt; Changing the function signature of __setitem__ to take a SIP_PYTUPLE as<br>
&gt; the first argument also does not help, although it does change the<br>
&gt; sipParseArgs format to &quot;TP0&quot; (e.g.,<br>
&gt; sipParseArgs(&amp;sipArgsParsed,sipArgs,&quot;TP0&quot;,&amp;PyTuple_Type,&amp;a0,&amp;a1)).  I<br>
&gt; suspect this call would succeed if there was a way to make sipParseArgs<br>
&gt; put the first n-1 sipArgs into a0 and the last argument into a1.<br>
&gt;<br>
&gt; The parsing of arguments for other methods with similar signature, e.g.,<br>
&gt; &quot;void afunc(SIP_PYOBJECT, SIP_PYOBJECT)&quot;, does indeed accept stuff like<br>
&gt; afunc((1,2), 0), so the problem appears to be with __setitem__.<br>
&gt;<br>
&gt; I could be doing something wrong as no one else appears to be having this<br>
<br>
&gt; problem.  If not, is there a some other way to force the argument parsing<br>
<br>
&gt; to put the first args into a tuple?  Or is there a way to do it by hand<br>
&gt; (like a NoArgParser for member functions)?    Currently, I modified the<br>
&gt; sip source (in sipgen/parser.c:findFunction, line 7642, {&quot;__setitem__&quot;,<br>
&gt; &quot;setitem_slot, TRUE, -1}) to not check the # of arguments to<br>
&gt; __setitem__/__getitem__.   For the time being, this gives the behaviour<br>
of<br>
&gt; the older version, so that I can remain using my old sip files (like the<br>
&gt; beginning of this post).<br>
<br>
Try tonight&#39;s SIP snapshot.<br>
<br>
Use __setitem__(SIP_PYTUPLE, SIP_PYOBJECT) and then unpack the tuple as you<br>
are in your __getitem__.<br>
<br>
Thanks,<br>
<font color="#888888">Phil<br>
</font></blockquote></div><br>