In older versions of sip (4.7.3), I have used __setitem__, __getitem__ to access/set elements from multidimensional quantities of a wrapped c++ object that uses operator()(int,int). For example, the following sip code used to work fine
class A { int operator()(int x,int y) const; int __getitem__(int x,int y) const; %MethodCode ... %End void __setitem__(int x,int y, int val) const; %MethodCode ... %End }; >From the ChangeLog this feature seemed to have been removed (in a related mailing list post, it was reported that the above usage was a bug http://article.gmane.org/gmane.comp.python.pyqt-pykde/12342/match=sip+__setitem__). With the new checking (sip 4.7.9, possibly earlier), the above code will now give an error (e.g., sip: A.sip:18: Incorrect number of arguments to Python slot). The previous mailing list post (http://thread.gmane.org/gmane.comp.python.pyqt-pykde/12342) suggested to either not use __setitem__/__getitem__ for this purpose or to use a tuple. I updated my code and the tuples work fine for __getitem__, but I cannot seem to get the tuple to work for __setitem__. For example, A.sip: class A { int __getitem(int x,int y); %MethodCode //This is just a dummy, actually parse the tuple and extract indices... %End void __setitem__(SIP_PYOBJECT, SIP_PYOBJECT); %MethodCode //Do something here.... %End }; Python test: from A import A a = A(10,10) # Getting works fine, no error parsing arguments b = a[0,0] b = a[0] # Setting works with anything but tuple a[0] = 1 # Works fine a[[1,2]] = 1 # Also works, but is not really a desired syntax a[0:5] = 1 # Works, would check for this when parsing args. a[(0,1)] = 1 # Error: "TypeError: too many arguments to A.__setitem__(), 2 at most expected" a[0,1] = 1 # Same error tup = (0,1) a[tup] = 1 # Same error The tuple always gets unpacked into more than one argument for __setitem__ and causes the TypeError, which happens before any of the sip %MethodCode can be called. Looking at the generated code for the __setitem__, the parsing of args looks something like: sipParseArgs(&sipArgsParsed,sipArgs,"P0P0",&a0,&a1) On the other hand, the parsing of args for __getitem__ seems to work due to the single arg format of "1P0". Manually editing the generated code to return the args packed into a single tuple (including the set value) like __getitem__ works but is not a satisfying solution. Changing the function signature of __setitem__ to take a SIP_PYTUPLE as the first argument also does not help, although it does change the sipParseArgs format to "TP0" (e.g., sipParseArgs(&sipArgsParsed,sipArgs,"TP0",&PyTuple_Type,&a0,&a1)). I suspect this call would succeed if there was a way to make sipParseArgs put the first n-1 sipArgs into a0 and the last argument into a1. The parsing of arguments for other methods with similar signature, e.g., "void afunc(SIP_PYOBJECT, SIP_PYOBJECT)", does indeed accept stuff like afunc((1,2), 0), so the problem appears to be with __setitem__. I could be doing something wrong as no one else appears to be having this problem. If not, is there a some other way to force the argument parsing to put the first args into a tuple? Or is there a way to do it by hand (like a NoArgParser for member functions)? Currently, I modified the sip source (in sipgen/parser.c:findFunction, line 7642, {"__setitem__", "setitem_slot, TRUE, -1}) to not check the # of arguments to __setitem__/__getitem__. For the time being, this gives the behaviour of the older version, so that I can remain using my old sip files (like the beginning of this post). Thanks, Neil Birkbeck _______________________________________________ PyQt mailing list PyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt