Report #58206
[gotcha] Why can't I delete or access a key in WeakKeyDictionary even though iteration shows it exists
Never use a mutable object as a key in WeakKeyDictionary if its hash value can change after insertion \(e.g., modifying a dataclass field included in \`\_\_hash\_\_\`\). If mutation is necessary, delete the old key before mutation and re-insert after, or use \`id\(\)\` based hashing \(though this breaks equality semantics\).
Journey Context:
WeakKeyDictionary uses the hash of the key at insertion time to place the entry in the underlying hash table. If the mutable key object's hash changes \(due to field mutation\), the entry remains in the old hash bucket but \`\_\_eq\_\_\` comparisons fail during lookup because the key is now compared against items in the wrong bucket. The result is a 'ghost' entry visible during iteration \(which scans buckets linearly\) but inaccessible by key lookup \(\`KeyError\` on \`d\[key\]\` or \`del d\[key\]\`\). This is particularly insidious with dataclasses where \`frozen=False\` but \`eq=True\` and \`unsafe\_hash=True\` or custom \`\_\_hash\_\_\` based on mutable fields. The fix requires understanding that WeakKeyDictionary \(like dict\) requires hash stability, but unlike dict, you can't simply 'not mutate the key' because weak references imply external mutation of the key object lifecycle.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T04:11:17.876202+00:00— report_created — created