This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: WeakKeyDictionary should support lookup by id instead of hash
Type: enhancement Stage:
Components: Library (Lib) Versions: Python 3.11, Python 3.10, Python 3.9, Python 3.8, Python 3.7, Python 3.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: andrei.avk, brandtbucher, conchylicultor, josh.r, youtux
Priority: normal Keywords:

Created on 2021-05-15 08:42 by conchylicultor, last changed 2022-04-11 14:59 by admin.

Messages (4)
msg393707 - (view) Author: Etienne POT (conchylicultor) * Date: 2021-05-15 08:42
WeakKeyDictionary are great to "associate additional data with an object owned by other parts of an application", as quoted from the doc: https://docs.python.org/3/library/weakref.html#weakref.WeakKeyDictionary

However, this currently only works for hashable types. Non-hashables are not supported:

```
@dataclass
class A:
  pass

a = A()

d = weakref.WeakKeyDictionary()
d[a] = 3  # TypeError: unhashable type: 'A'
```

With regular dict, this could be easilly solved by using `d[id(a)] = 3`, but WeakKeyDictionary don't accept `int` of course. I cannot wrap the object either as the weakref would not be attached to the original object, but the wrapper.

It would be great to be able to force WeakKeyDictionary to perform lookup on `id` internally. Like `d = WeakKeyDictionary(use_id_lookup=True)`
msg396362 - (view) Author: Andrei Kulakov (andrei.avk) * (Python triager) Date: 2021-06-22 20:31
Maybe I am misunderstanding, but if an object is deleted, and another object created with the same ID, wouldn't WeakRefDict now be pointing to the wrong object?
msg396451 - (view) Author: Josh Rosenberg (josh.r) * (Python triager) Date: 2021-06-24 03:09
Andrei: If designed appropriately, a weakref callback attached to the actual object would delete the associated ID from the dictionary when the object was being deleted to avoid that problem. That's basically how WeakKeyDictionary works already; it doesn't store the object itself (if it did, that strong reference could never be deleted), it just stores a weak reference for it that ensures that when the real object is deleted, a callback removes the weak reference from the WeakKeyDictionary; this just adds another layer to that work.

I don't think this would make sense as a mere argument to WeakKeyDictionary; the implementation would differ significantly, and probably deserves a separate class.
msg396452 - (view) Author: Andrei Kulakov (andrei.avk) * (Python triager) Date: 2021-06-24 04:09
Josh: thanks for the explanation, this makes sense.
History
Date User Action Args
2022-04-11 14:59:45adminsetgithub: 88306
2021-08-26 22:27:51youtuxsetnosy: + youtux
2021-06-24 04:09:17andrei.avksetmessages: + msg396452
2021-06-24 03:09:57josh.rsetnosy: + josh.r
messages: + msg396451
2021-06-22 20:31:48andrei.avksetnosy: + andrei.avk
messages: + msg396362
2021-05-21 19:52:25brandtbuchersetnosy: + brandtbucher
2021-05-15 08:42:51conchylicultorcreate