Open
Description
Bug report
Bug description:
After reusing one object's __dict__
for another object, and adding a reference to the original object in a dictionary on the target object, the original object might get collected too early (and cause a whole other dictionary to get cleared). I hope the code below describes it better than my words.
I've bisected this problem to c32dc47.
This is the smallest reproduction I've found so far:
import gc
import sys
print(sys.version_info)
class A:
def __del__(self):
print("del", hex(id(self)))
a = A()
a.attr_a = "test value"
b = A()
b.__dict__ = a.__dict__
b.other_attr = {"self reference": a, "other data": 42}
del a
print("before gc:", b.__dict__)
gc.collect()
print("after gc:", b.__dict__)
Results on 3.13:
sys.version_info(major=3, minor=13, micro=0, releaselevel='alpha', serial=5)
before gc: {'attr_a': 'test value', 'other_attr': {'self reference': <__main__.A object at 0x76cc6317a900>, 'other data': 42}}
del 0x76cc6317a900
after gc: {'attr_a': 'test value', 'other_attr': {}}
del 0x76cc6256ccd0
Results on 3.12, and what I expected to see:
sys.version_info(major=3, minor=12, micro=7, releaselevel='final', serial=0)
before gc: {'attr_a': 'test value', 'other_attr': {'self reference': <__main__.A object at 0x77496b531130>, 'other data': 42}}
after gc: {'attr_a': 'test value', 'other_attr': {'self reference': <__main__.A object at 0x77496b531130>, 'other data': 42}}
del 0x77496b531160
del 0x77496b531130
I've noticed this change in behaviour while working with Locust.io, the original issue for reference: locustio/locust#3050
CPython versions tested on:
3.13, CPython main branch
Operating systems tested on:
Linux