Clearing out handlers in logging?

Tim Chase python.list at tim.thechases.com
Sun Mar 16 08:57:59 EDT 2014


On 2014-03-16 09:39, Gunther Dietrich wrote:
> Tim Chase <python.list at tim.thechases.com> wrote:
> 
> >The current (2.7; maybe 3.x?) logging module doesn't have any sort
> >of "clear out all the current handlers" method.
> 
> Indeed, THERE IS a removeHandler() method.

Yes, I'm aware of it, having read the source & docs.  However, the
signature is

  removeHandler(some_handle_to_a_handler_that_you_already_have)

and at the point in my code where I need to override this,
basicConfig() has already assigned a default stream handler and
discarded the handle/name/reference to it because
the .debug/.info/.warn/.error/.critical methods of all call
basicConfig() if there aren't any handlers.

[Aside: which is non-pythonically, using "if len(self.handlers) == 0"
instead of "if not self.handlers" in addition to the camel-case
naming (which would be much harder to fix)]

> >>> for handler in log.handlers:
> ...     log.removeHandler(handler)
> 
> I think, that's just one of the tasks that removeHandler() was
> written for.

The question revolves mostly around dipping your hands into the
undocumented .handlers property.  I can nuke it directly (and looking
at least at the 2.7 source, there doesn't seem to be much issue with
doing this), or I can iterate (as modified by Chris Angelico to
prevent modifying the list over which you're iterating). Either way,
it still involves reaching into log.handlers which doesn't appear in
any of the documentation as far as I could find.

So yes, I use help() and dir() on a daily basis.  But just because
something is there doesn't mean I should go mucking with it in the
event it's undocumented.  If it *should* be trusted as a publicly
available interface, it should be documented; if it shouldn't be
treated publicly, then it should have a way to iterate over them
such as

  def iterHandlers(self):
    for h in self.handlers[:]:
      yield h

so you can do

  for h in log.iterHandlers():
    log.removeHandler(h)

Given how stable this code has been over the years, I'd just document
the log.handlers property and possibly advise to lock around messing
with it (unless "del log.handlers[:]" is atomic).

-tkc









More information about the Python-list mailing list