wxPython and reference counts

Hi,

I have been attempting to solve a problem with the reference counts of a COM object, preventing it from being freed. After more than a year I've discovered it only occurs when in the wxPython MainLoop(). I have included two files: main.py and itunes.py.

Here is the output from running the main.py with gui set to False:

OnAboutToPromptUserToQuitEvent
self.iTunes ref count: 2
self.Events ref count: 2
InterfaceCount: 0
GatewayCount: 0

With gui set to True, the following occurs:

OnAboutToPromptUserToQuitEvent
self.iTunes ref count: 2
self.Events ref count: 8
InterfaceCount: 1
GatewayCount: 3
OnCOMCallsDisabledEvent
OnCOMCallsEnabledEvent
OnQuittingEvent
OnCOMCallsDisabledEvent

The reference count does not decrease after the objects are deleted, and events are still dispatched. If the MainLoop() is used, the reference count of the COM object is retained when it is deleted. If anyone can offer any suggestions to reduce the reference count when wxPython is used I would be grateful.

Cheers,
Dave

main,py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import itunes
import time
from wxPython.wx import *

wxID_TIMER = 1001
gui = False

class TaskBarApp(wxFrame):
     def __init__(self, parent, id, title):
         wxFrame.__init__(self, parent, id, title, size = (1,1), style=wxFRAME_NO_TASKBAR)
         self.timer = wxTimer(self, wxID_TIMER)
         self.Bind(EVT_TIMER, self.OnTimer, id=wxID_TIMER)
         self.timer.Start(1000)

     def OnTimer(self,event):
         itunes.pumpevents()

class MyApp(wxApp):
     def OnInit(self):
         frame = TaskBarApp(None, -1, "MyApp")
         frame.Center(wxBOTH)
         frame.Show(false)
         return true

if __name__ == "__main__":
     itunes = itunes.iTunesConnection()
     itunes.connect()

     if gui:
         app = MyApp(0)
         app.MainLoop()
     else:
         while True:
      itunes.pumpevents()
      time.sleep(1)

itunes.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pythoncom
import win32com.client
import gc
import sys

class iTunesConnection:
     def __init__(self):
         pass

     def pumpevents(self):
         pythoncom.PumpWaitingMessages()
         if hasattr(self,"Events"):
      if self.Events.quit:
        self.cleanup()

     def cleanup(self):
         pythoncom.CoUninitialize()
         pythoncom.CoFreeUnusedLibraries()
         print "self.iTunes ref count: %s" % sys.getrefcount(self.iTunes)
         print "self.Events ref count: %s" % sys.getrefcount(self.Events)
         del self.Events
         del self.iTunes
         gc.collect()
         print "InterfaceCount: %s" % pythoncom._GetInterfaceCount()
         print "GatewayCount: %s" % pythoncom._GetGatewayCount()

     def connect(self):
         pythoncom.CoInitialize()
         self.iTunes = win32com.client.dynamic.Dispatch("iTunes.Application")
         self.Events = win32com.client.WithEvents(self.iTunes, iTunesEvents)

class iTunesEvents:
     def __init__(self):
         self.quit = False

     def OnAboutToPromptUserToQuitEvent(self):
         print "OnAboutToPromptUserToQuitEvent"
         self.quit = True

     def OnQuittingEvent(self):
         print "OnQuittingEvent"
         self.quit = True

     def OnCOMCallsDisabledEvent(self,code):
         print "OnCOMCallsDisabledEvent"

     def OnCOMCallsEnabledEvent(self):
         print "OnCOMCallsEnabledEvent"

     def OnPlayerPlayEvent(self,track):
         print "OnPlayerPlayEvent"

     def OnPlayerStopEvent(self,track):
         print "OnPlayerStopEvent"

     def OnPlayerPlayingTrackChangedEvent(self,track):
         print "OnPlayerPlayingTrackChangedEvent"