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

Guido van Rossum guido@python.org
Thu, 27 Feb 2003 10:22:22 -0500


> 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>

I cannot find that article by id alone; groups.google.com doesn't have
it.

> <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__*"

I'm guessing this should be indented the same as the following line.

>         def __del__(cls):
>             print 'deleted', cls.__name__
> 
> class MyClass(object):
>     if 'meta' in sys.argv:
>  print "*meta*"

Ditto.

>      __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 ...

In general objects whose class has a __del__ method are not
collectible.  The GC implementation has a good reason for this;
someone else may be able to explain it.

--Guido van Rossum (home page: http://www.python.org/~guido/)