[Python-Dev] bug? classes whose metclass has __del__ are not collectible

Samuele Pedroni pedronis@bluewin.ch
Thu, 27 Feb 2003 13:48:43 +0100


new-style classes keep track of their subclasses through weak-refs so they
remain in general collectible.

consider this code:  (inspired by this post comp.lang.python post
id: <b3khka$2g6$1@news.wplus.spb.ru>
)

<test.py>
import sys

class MyMetaclass(type):

    def __init__(cls, name, bases, dict):
        super(MyMetaclass, cls).__init__(name, bases, dict)
        print 'initialized', cls.__name__

    if 'meta__del__' in sys.argv:
 print "*meta__del__*"
        def __del__(cls):
            print 'deleted', cls.__name__

class MyClass(object):
    if 'meta' in sys.argv:
 print "*meta*"
     __metaclass__ = MyMetaclass
    pass

class Sub(MyClass):
    pass

del Sub

import gc

gc.collect() # force involved weak-refs to be cleared

print "MyClass subclasses",MyClass.__subclasses__()
print "garbage",gc.garbage

</test.py>

Now:

C:\exp\py-subclasses-gc>\transit\Py23\python test.py
MyClass subclasses []
garbage []

C:\exp\py-subclasses-gc>\transit\Py23\python test.py meta
*meta*
initialized MyClass
initialized Sub
MyClass subclasses []
garbage []

also Sub with both metaclass type or MyMetaclass without __del__ is collectible
and collected but:

C:\exp\py-subclasses-gc>\transit\Py23\python test.py meta meta__del__
*meta__del__*
*meta*
initialized MyClass
initialized Sub
MyClass subclasses [<class '__main__.Sub'>]
garbage [<class '__main__.Sub'>]

if MyMetaclass grows a __del__ method Sub is no longer collectible ...