From f3116ad4d00ed2aaaf83d6cadb4c9e1d21e364d8 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Fri, 29 Jan 2016 18:36:21 +0000 Subject: [PATCH] [loggingTools] add Logger class with support for 'lastResort' stderr handler Both _StderrHandler and Logger.callHandlers included here are taken from Python 3.5's logging.py source. I only set logging.lastResort if it's not already set (i.e. for Python < 3.2). --- Lib/fontTools/misc/loggingTools.py | 52 ++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/Lib/fontTools/misc/loggingTools.py b/Lib/fontTools/misc/loggingTools.py index f2a302ea7..04a435d02 100644 --- a/Lib/fontTools/misc/loggingTools.py +++ b/Lib/fontTools/misc/loggingTools.py @@ -87,6 +87,58 @@ class LevelFormatter(logging.Formatter): return super(LevelFormatter, self).format(record) +class _StderrHandler(logging.StreamHandler): + """ This class is like a StreamHandler using sys.stderr, but always uses + whatever sys.stderr is currently set to rather than the value of + sys.stderr at handler construction time. + """ + def __init__(self, level=logging.NOTSET): + """ + Initialize the handler. + """ + logging.Handler.__init__(self, level) + + @property + def stream(self): + return sys.stderr + + +if not hasattr(logging, 'lastResort'): + # for Python pre-3.2, set a "last resort" handler used when clients don't + # explicitly configure logging + logging.lastResort = _StderrHandler(logging.WARNING) + + +class Logger(logging.Logger): + """ Add support for 'lastResort' handler introduced in Python 3.2. + You can set logging.lastResort to None, if you wish to obtain the pre-3.2 + behaviour. Also see: + https://docs.python.org/3.5/howto/logging.html#what-happens-if-no-configuration-is-provided + """ + + def callHandlers(self, record): + # this is the same as Python 3.5's logging.Logger.callHandlers + c = self + found = 0 + while c: + for hdlr in c.handlers: + found = found + 1 + if record.levelno >= hdlr.level: + hdlr.handle(record) + if not c.propagate: + c = None # break out + else: + c = c.parent + if (found == 0): + if logging.lastResort: + if record.levelno >= logging.lastResort.level: + logging.lastResort.handle(record) + elif logging.raiseExceptions and not self.manager.emittedNoHandlerWarning: + sys.stderr.write("No handlers could be found for logger" + " \"%s\"\n" % self.name) + self.manager.emittedNoHandlerWarning = True + + def configLogger(**kwargs): """ Do basic configuration for the logging system. This is more or less the same as logging.basicConfig with some additional options and defaults.