-
-
Notifications
You must be signed in to change notification settings - Fork 32k
Materialized instance dictionaries are not GC-tracked #133543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thanks for the report. Do you have a smaller, simpler reproducer? Ideally fewer than 10 lines or so, with no |
Minimal reproducer: import gc
import weakref
class C:
pass
o = C()
# Comment out this line to "fix" the leak:
o.__dict__
# Set exactly 30 attributes, one of which is a cycle:
o.cycle = o
for i in range(29):
setattr(o, f"attr_{i}", None)
# o is only reachable through the weakref:
ref = weakref.ref(o)
del o
gc.collect()
assert ref() is None, "o is leaked!" Confirmed leak on 3.13, works fine on 3.12 and 3.14. Probably related to lazy |
Ah, this is super subtle. When the dictionary is materialized with |
This patch for the 3.13 branch fixes the reproducer: diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 680d6beb760..932be96827f 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -6838,6 +6838,7 @@ store_instance_attr_lock_held(PyObject *obj, PyDictValues *values,
value == NULL ? PyDict_EVENT_DELETED :
PyDict_EVENT_MODIFIED);
_PyDict_NotifyEvent(interp, event, dict, name, value);
+ MAINTAIN_TRACKING(dict, name, value);
}
FT_ATOMIC_STORE_PTR_RELEASE(values->values[ix], Py_XNewRef(value)); I haven't looked into why 3.14 is fine yet. |
All dictionaries are tracked now: GH-127027 |
Amazing! I'm sorry about the very large reproducer. |
Uh oh!
There was an error while loading. Please reload this page.
Bug report
Bug description:
Objects can't be garbage collected after accessing
__dict__
. The issue was noticed on a class with manycached_property
which store the cache entries by directly accessing the instance__dict__
.If
cached_property
is modified by removing this line, the issue goes away:https://github.com/python/cpython/blob/3.13/Lib/functools.py#L1028
The attached reproduction creates instances of two classes and checks if they are freed or not.
Reproduction of the issue with the attached pytest test cases:
CPython versions tested on:
3.13
Operating systems tested on:
Linux
Linked PRs
The text was updated successfully, but these errors were encountered: