fork(1) download
  1. from weakref import WeakKeyDictionary, WeakValueDictionary
  2.  
  3. class Id:
  4. def __init__(self, key):
  5. self._id = id(key)
  6. def __hash__(self):
  7. return self._id
  8. def __eq__(self, other):
  9. return self._id == other._id
  10.  
  11. class WeakUnhashableKeyDictionary:
  12. def __init__(self, *args, **kwargs):
  13. # TODO Do something to initialize given args and kwargs.
  14. self.keys = WeakValueDictionary()
  15. self.values = WeakKeyDictionary()
  16.  
  17. def __getitem__(self, key):
  18. return self.values.__getitem__(Id(key))
  19.  
  20. def __setitem__(self, key, value):
  21. _id = Id(key)
  22. # NOTE This works because key holds on _id iif key exists,
  23. # and _id holds on value iif _id exists. Transitivity. QED.
  24. # Because key is only stored as a value, it does not need to be hashable.
  25. self.keys.__setitem__(_id, key)
  26. self.values.__setitem__(_id, value)
  27.  
  28. def __delitem__(self, key):
  29. self.keys.__delitem__(Id(key))
  30. self.values.__delitem__(Id(key))
  31.  
  32. class Key:
  33. __hash__ = None
  34.  
  35. d = WeakUnhashableKeyDictionary()
  36. l = [Key(), Key(), Key()]
  37. d[l[0]] = 1
  38. d[l[1]] = 2
  39.  
  40. for k in d.keys.values():
  41. l.remove(k)
  42. try:
  43. print(d[Key()])
  44. print('False match detected!')
  45. except KeyError:
  46. pass
Success #stdin #stdout 0.04s 9748KB
stdin
Standard input is empty
stdout
1
False match detected!