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

Reply via email to