Open
Description
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