import stackless
import gc
import sys


class wrapper(object):
    # no instance __dict__ please
    __slots__ = ['name', '_tasklet']

    def __init__(self, name):
        self.name = name
        self._tasklet = stackless.tasklet(self.f)()

    def f(self):
        try:
            print 'Running', self.name
            stackless.schedule_remove()
        finally:
            print 'Cleaning up', self.name

    def __del__(self):
        print 'Destructor of', self.name
        self._tasklet.kill()


def print_referrers(o):
    gc.collect()
    this_frame = sys._getframe(0)
    print 'Referrers of %s:' % o
    for r in gc.get_referrers(o):
        if r is this_frame:
            continue

        try:
            d = r.f_code.co_name
            print '  - %s (%s)' % (r, d)
        except AttributeError:
            print '  - %s' % (r,)


def main():
    # debug memory leaks
    gc.set_debug(gc.DEBUG_LEAK)

    w = wrapper('w')
    stackless.schedule()

    print_referrers(w)

    del w
    gc.collect()


if __name__ == '__main__':
    main()
