[PySide] Bug with new hash table feature

Nathan Smith nathanjsmith at gmail.com
Wed May 30 21:19:07 CEST 2012


There had better never be an address at -1 or the hash function won't work
right.  The Python documentation (
http://docs.python.org/c-api/typeobj.html#PyTypeObject.tp_hash) says that
hash should only return -1 if there was an exception set.  If it's possible
to have an address -1, then we need a different hash function than just
returning address.

We may want to do this differently anyway because the current hash approach
is incompatible with weakref.WeakSet.

>>> from PySide import QtCore
>>> import weakref
>>> objs = weakref.WeakSet()
>>> a = QtCore.QObject()
>>> b = QtCore.QObject(a)
>>> objs.update([a,b])
>>> del a
>>> objs.remove(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.7/_weakrefset.py", line 105, in remove
    self.data.remove(ref(item))
RuntimeError: Internal C++ object (PySide.QtCore.QObject) already deleted.


I use weaksets extensively in my application to hold weak references to Qt
objects.  In the example above, when 'a' is deleted its reference is
removed from the WeakSet automatically.  b points at an invalid object, but
its reference count remains high so it isn't removed from the WeakSet.
 When I try to remove b from the WeakSet manually (objs.remove(b)), a
RuntimeError is raised because weak references apparently rely on the
hashing function.  So now a weak reference to 'b' is stuck in the WeakSet *
forever*.

Can we use the address of the Shiboken object as the hash value?  That
remains valid so long as there are references to the object, even after the
object itself has been deleted in C++ land.

Nathan

On Wed, May 30, 2012 at 1:53 PM, John Ehresman <jpe at wingware.com> wrote:

> On 5/30/12 2:46 PM, Nathan Smith wrote:
>
>> Thanks John!  I was returning 0L, but changed it to -1L.  The hash
>> function now raises a RuntimeError when called on an invalid object.
>>  I've opened bug PYSIDE-72 for this and will attach an updated patch to
>> it using the -1L return.
>>
>
> Took a peek at it -- you might want to test the return value in the non
> exception case and return -2 if it's -1.  I don't know if it's guaranteed
> that an address can never be the bit value of -1.
>
> John
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/pyside/attachments/20120530/ab1b8369/attachment.html>


More information about the PySide mailing list