Index: Lib/logging/__init__.py =================================================================== --- Lib/logging/__init__.py (revision 76505) +++ Lib/logging/__init__.py (working copy) @@ -24,6 +24,7 @@ """ import sys, os, time, cStringIO, traceback, warnings +import weakref __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO', @@ -593,6 +594,23 @@ _handlers = {} #map of handler names to handlers _handlerList = [] # added to allow handlers to be removed in reverse of order initialized +def _removeHandlerRef(wr): + #get the module data lock, as we're updating a shared structure. + _acquireLock() + try: #unlikely to raise an exception, but you never know... + if wr in _handlerList: + _handlerList.remove(wr) + finally: + _releaseLock() + +def _addHandler(handler): + #get the module data lock, as we're updating a shared structure. + _acquireLock() + try: #unlikely to raise an exception, but you never know... + _handlerList.insert(0, weakref.ref(handler, _removeHandlerRef)) + finally: + _releaseLock() + class Handler(Filterer): """ Handler instances dispatch logging events to specific destinations. @@ -611,12 +629,8 @@ self._name = None self.level = _checkLevel(level) self.formatter = None - #get the module data lock, as we're updating a shared structure. - _acquireLock() - try: #unlikely to raise an exception, but you never know... - _handlerList.insert(0, self) - finally: - _releaseLock() + # Add the handler to the global _handlerList (for cleanup on shutdown) + _addHandler(self) self.createLock() def get_name(self): @@ -724,7 +738,7 @@ """ Tidy up any resources used by the handler. - This version does removes the handler from an internal list + This version does remove the handler from an internal list of handlers which is closed when shutdown() is called. Subclasses should ensure that this gets called from overridden close() methods. @@ -734,7 +748,6 @@ try: #unlikely to raise an exception, but you never know... if self._name and self._name in _handlers: del _handlers[self._name] - _handlerList.remove(self) finally: _releaseLock() @@ -1532,10 +1545,11 @@ Should be called at application exit. """ - for h in handlerList[:]: + for wr in handlerList[:]: #errors might occur, for example, if files are locked #we just ignore them if raiseExceptions is not set try: + h = wr() h.flush() h.close() except: