We don't want to raise a RuntimeError when calling the hash function in Shiboken because of the very reason you stated. Doing something that raises exceptions in the hash function will break any container that uses hashes (weak references, sets, dicts, weakref.WeakSet, probably many more). Returning default error values has a similar effect.
My most recent approach was to return the address of the shiboken object, which is address of the PyObject. I tried this approach (I haven't submitted it yet) on the example you provided below, and it seems to work. I've been using it with my code for a few days now, and it's been working well. Note that using the address method has the drawback that two objects separated in time may have the same hash value because they may land at the same memory address. You can see this in the following test case: >>> hash(QtCore.QObject()) == hash(QtCore.QObject()) True The first QObject is created, the hash is taken of it, and then it is destroyed. The reference count drops to 0, so the Shiboken handle is cleaned up. A second QObject is created (at the same address as the first QObject), the hash is taken of it, and then it is destroyed. This could be avoided if we kept a running counter of SbkObject instances and used the counter as the hash value (which I think is overkill). Incidentally, what is the difference between shiboken.delete and shiboken.invalidate? There don't appear to be any docstrings in the shiboken module and invalidate isn't in the online documentation. Nathan On Wed, Jun 13, 2012 at 3:45 PM, John Ehresman <[email protected]> wrote: > On 5/30/12 3:35 PM, John Ehresman wrote: > >> 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. >>> >> >> This works if there can only be one wrapper at a time for a given >> QObject. I don't know if this is the case. >> > > I just ran into this bug and tried to apply the patch locally, but ran > into poblems. If the address of the PyObject* can be used, I think that > would be preferable. Consider the following: > > o = QObject() > d = {} > d[o] = 1 > def on_destroy(): > d.pop(o) > o.destroyed.connect(on_**destroy) > shiboken.delete(o) > > The pop in the destroy handler will fail with a RuntimeError and even if > the RuntimeError is suppressed and a default hash value returned, the entry > in the dictionary won't be found or removed. > > John >
hash.patch
Description: Binary data
_______________________________________________ PySide mailing list [email protected] http://lists.qt-project.org/mailman/listinfo/pyside
