[PyQt] Bug in QAbstractItemModel::createIndex()?

Phil Thompson phil at riverbankcomputing.co.uk
Fri Apr 6 12:25:31 BST 2007


On Friday 06 April 2007 11:43 am, Andreas Pakulat wrote:
> On 06.04.07 10:44:13, Phil Thompson wrote:
> > On Friday 06 April 2007 10:10 am, Andreas Pakulat wrote:
> > > I've put an PyErr_Print(); into the if-part and here's the output (the
> > > object parsing block is printed when in QtCore the 2nd block with the
> > > pointer is executed). So as far as I can see the problem is that id()
> > > returns a long int, but its going to be converted to an int and that
> > > fails...
> > >
> > > emodel>python simpletreemodel.py
> > > ....
> > > -------------------------
> > > OverflowError: long int too large to convert to int
> > > -------------------------
> > > Object parsing block
> > > -------------------------
> > > OverflowError: long int too large to convert to int
> > > -------------------------
> > > Object parsing block
> > > -------------------------
> > > OverflowError: long int too large to convert to int
> > > -------------------------
> > > Object parsing block
> >
> > And I guess if you change the call to PyLong_AsLong() instead of
> > PyInt_AsLong() then it would call the right overload.
>
> Uhm, no. Just changing the PyInt_AsLong to PyLong_AsLong gives new
> errors. You know I don't really know what I'm doing here, I have no idea
> how sip itself works or how wrapping C++ code with sip works...

What new errors?

> > So the question is...
> >
> > Should SIP quietly lose the extra bits, or should it raise an exception.
>
> Well, unless I'm mistaken this would still mean that internalId() !=
> id(object), if id() returns a value that is outside the int-range. So I
> don't think thats a good solution.

But it's the "correct" solution as a C++ application would have the same 
problem.

> Unless its possible to make sure id() returns a 32-bit int I don't think
> there's a proper solution for this, except writing your own way of
> getting an properly-sized integer for a given object. So a
> big-fat-warning on the createIndex() and internalId() functions that
> they don't necessarily work with id() is advised.

It is possible to get it to work with Python by changing the PyQt signature on 
the first createIndex() overload to take a long rather than int and to 
actually call the other createIndex() overload with an appropriate cast. That 
way no bits will be lost. However that would make the PyQt version work 
differently (better) than the C++ version.

> Also if internalPointer works properly I don't think the id-thing is
> needed. After all with the pointer you don't necessarily need to keep
> the list around if you create a tree structure with your objects.

Yes. With hindsight I shouldn't have wrapped the first createIndex() overload 
and internalId() in the first place, but at the time I wrapped the second 
overload and internalPointer() as using a void* instead of a Python object 
which made it unusable.

I've decided not to change SIP at all - the current behaviour is a bug which 
needs fixing at some stage, but it's only the particular createIndex() 
overload signatures that are triggering it.

Phil


More information about the PyQt mailing list