#!/usr/bin/python

"""
Automatic free-list management for user-defined classes.

Jp Calderone, Jan 2004
"""

import gc

class FreeListTypeType(type):
    def __new__(outer_cls, name, bases, attrs):
        fl = attrs['freelist'] = []

        oldnew = attrs.get('__new__')
        if oldnew:
            def __new__(inner_cls, *args, **kwargs):
                if fl:
                    return fl.pop()
                return oldnew(inner_cls, *args, **kwargs)
        else:
            def __new__(inner_cls, *args, **kwargs):
                if fl:
                    return fl.pop()
                return super(outer_cls.__class__, inner_cls).__new__(inner_cls, *args, **kwargs)
        attrs['__new__'] = __new__
        
        olddel = attrs.get('__del__')
        if olddel:
            def __del__(self):
                olddel(self)
                if len(gc.get_referrers(self)) == 3:
                    fl.append(self)
        else:
            def __del__(self):
                try:
                    supdel = super(ThisClass, self).__del__
                except AttributeError:
                    pass
                else:
                    supdel()
                    del supdel
                if len(gc.get_referrers(self)) == 3:
                    fl.append(self)
        attrs['__del__'] = __del__

        ThisClass = type.__new__(outer_cls, name, bases, attrs)
        return ThisClass

class FreeListType(object):
    __metaclass__ = FreeListTypeType


class FreeListed(FreeListType):
    pass

class NotFreeListed(object):
    pass

if __name__ == '__main__':
    for i in range(2):
        print [FreeListed(), FreeListed()]
        print [NotFreeListed(), NotFreeListed()]

