Bug report
The dict.update() modification check can be erroneously triggered by modifications to different dictionaries that happen to share the underlying keys objects.
For example, in the following program, the creation and modification of the f2 object can lead to an incorrect RuntimeError raised in the main thread that operates on distinct dictionaries.
import time import threading b = threading.Barrier(2) class Foo: pass class MyStr(str): def __hash__(self): return super().__hash__() def __eq__(self, other): time.sleep(0.1) return super().__eq__(other) def thread(): b.wait() time.sleep(0.05) f2 = Foo() f2.a = "a" f2.b = "b" f2.c = "c" def main(): t1 = threading.Thread(target=thread) t1.start() b.wait() f1 = Foo() f1.a = "a" f1.b = "b" x = {} x[MyStr("a")] = MyStr("a") x.update(f1.__dict__) t1.join() if __name__ == "__main__": main()
Traceback (most recent call last):
File "/home/sgross/cpython/bad.py", line 44, in <module>
main()
~~~~^^
File "/home/sgross/cpython/bad.py", line 39, in main
x.update(f1.__dict__)
~~~~~~~~^^^^^^^^^^^^^
RuntimeError: dict mutated during update