Q:

pygtk notebook page close memory leak

I have a notebook that contains pages with tabs that have close buttons in them. When you click on the button, the page in that tab is then removed from the notebook( closed).
The problem is that when the tab closes, the memory is never freed, because there seems to be something still referencing the destroyed page.
Here is some sample code for my notebook:
notebook = gtk.Notebook
def create_tab():
    page = gtk.Label( "THis is a page")
    page.show()
    tab = gtk.HBox()#The custom tab-label widget
    tab_label = gtk.Label( "Tab")
    tab_label.show()
    tab.pack_start( tab_label)
    tab_close = gtk.Button()
    tab_close.set_image(gtk.image_new_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU))
    tab_close.connect( 'clicked', destroy_tab, page )
    tab_close.show()
    tab.pack_end( tab_close)
    tab.show()

    notebook.append_page(page, tab)
def destroy_tab( widget, data=None):
    page_num = notebook.page_num( data )
    notebook.remove_page( page_num )
    data.destroy()

The create_tab function is a callback added to a button's clicked signal, so I can add as many pages to the notebook as I'd like. But when the page is removed from the notebook, through the destroy_tab callback, the page is successfully removed from the notebook, but the memory is never freed.
This link outlines the same problem I'm having. And one thing it suggests is that there is still a reference to the page through the custom widget set as the tab_label. I've also tried destroying the custom widget, even recursively destroying all of its children but still can't seem to figure out what is still referencing this page to keep it in memory. What could be the problem?

A:

I managed to figure out, through gc.getreferrers() that there was a circular reference
between the close button and the page that it was closing. Through further testing, I found out that it's of no fault of my own, but in the way that a GtkNotebook seems to link the two when they're added to the notebook. I did manage to get rid of that circular reference simply
by creating a custom button that holds a reference to the widget itself, so then, when the button is destroyed, that widget reference is set to None and that seems to successfully get rid of the reference.
However, this still doesn't seem to clear up the memory behind the page after it is closed.
Here's the revamped code:
class CloseButton(gtk.Button):
    def __init__(self, widget):
        gtk.Button.__init__(self)
        self.widget_ref = widget#Pass the widget reference to this button
        #Initialize the button here...
        self.connect( 'destroy', self.on_destroy )
    def on_destroy( self, widget ):
        self.widget_ref = None#Destroy the reference to the widget

And then, in the code you would use the button like so:
notebook = gtk.Notebook
def create_tab():
    page = gtk.Label( "THis is a page")
    page.show()
    tab = gtk.HBox()#The custom tab-label widget
    tab_label = gtk.Label( "Tab")
    tab_label.show()
    tab.pack_start( tab_label)
    tab_close = CloseButton(page)#pass a reference to page

    tab_close.connect( 'clicked', destroy_tab )
    tab_close.show()
    tab.pack_end( tab_close)
    tab.show()

    notebook.append_page(page, tab)

def destroy_tab( widget, data=None):
    page_num = notebook.page_num( widget.widget_ref )
    notebook.remove_page( page_num )
    widget.destroy()

And that does the trick! The reference disappears when the destroy method is called on the button

