On Tue, Dec 30, 2014 at 8:34 PM, Benjamin Peterson email@example.com wrote:
Why not just use a wrapper like this for keys?
class IdentityWrapper(object): def __init__(self, obj): self.obj = obj def __hash__(self): return id(self.obj) def __eq__(self, other): return self.obj is other
I considered an approach like this one, but couldn't quite make it work. How do we make the IdentityWrapper object vanish at the right time?
If we place it directly into a vanilla WeakKeyDictionary and forget it, it will immediately die and our WeakKeyDictionary will remove it. On the other hand, if we modify the IdentityWrapper to hold a weakref to obj, the IdentityWrapper will not vanish out of the dictionary at all, and its hash() will become invalid to boot (though we can deal with the latter issue relatively easily).
If we could somehow make the target incorporate a reference to the wrapper, that would probably solve these issues, but I can't see a general way to do that without potentially breaking the target. I could do something like target._Foo__backref = self (or equivalently, invoke Python's name mangling), but that's a sloppy solution at best and a recipe for name collisions at worst (what if the target's class has multiple instances of Foo() attached to it?). It also falls apart in the face of __slots__.
-- Kevin Norris