New submission from Kristján Valur Jónsson: Classes contain two kinds of cycles back to themselves: 1) in their __mro_ list, the class itself is typically the first member. 2) in the descriptors for various fields such as __dict__.
The problem here is that there is no way to break the cycle. A class that is dynamically created (e.g. in a function) and then not needed, will stick around until garbage collection is performed. This happens in spite of attempts within the core to avoid such cycles. For instance, the type's tp_subclasses list contains to avoid a cycle between a baseclass and its parent. A .py file demonstrating the problem is attached. A patch is attached that resolves the issue: 1) the mro tuple in the type object is "nerfed" to contain a Py_None reference in its first place, where it previously held the cyclic reference to the type object itself. This is then "fixed" in place where required. the __mro__ attribute becomes a getter that duplicates the tuple. 2) the descriptors are modified to hold a weak-reference to the target type, rather than a strong reference. 3) Fix process cleanup. The thread state cannot be released until after the cleanup of e.g. PySet_Fini() because the freeing of objects in there requires the DUSTBIN_SAFE macros that require the thread state. Cleanup behaviour probably changed since objects go away on their own now. 4) changes to test_gc.py in the testsuite reflecting the changed behaviour The patched code passes all the testsuite. ---------- components: Interpreter Core files: classleak.patch keywords: patch messages: 188875 nosy: kristjan.jonsson priority: normal severity: normal status: open title: Dynamic classes contain non-breakable reference cycles type: resource usage versions: Python 3.4 Added file: http://bugs.python.org/file30207/classleak.patch _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue17950> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com