Replace key if not identical to old key in dict by malthe · Pull Request #31685 · python/cpython (original) (raw)

This fixes an issue in dict and by extension in weakref.WeakKeyDictionary which arises when a key that is equal to an existing key is used to set a new value – where the key itself is not replaced.

To appreciate this situation, consider when the keys are type weakref.ref.

In this case, the lifetime of the key after replacing the value is now that of the initial key and not the one that's been set subsequently – since the key entry is still the initial object. If the first key falls to refcount zero, the key is removed from the weakref.WeakKeyDictionary – which is unexpected because we have set a newer key which might have refcount greater than zero.

In the general case where a value is replaced for the exact same key (object identity), there is no practical difference with this change – and when a new key is used to replace a value, the cost is only a write to memory.

Thanks to @potiuk and @ashb for helping finding this issue which was discovered during flaky test runs in Apache Airflow.