import logging import sys VERBOSITY = 3 # The root logger for the whole top-level package: _logger = logging.getLogger(__name__.rpartition('.')[0]) def configure_logger(logger, verbosity=VERBOSITY, *, logfile=None, maxlevel=logging.CRITICAL, ): level = max(1, # 0 disables it, so we use the next lowest. min(maxlevel, maxlevel - verbosity * 10)) logger.setLevel(level) #logger.propagate = False if not logger.handlers: if logfile: handler = logging.FileHandler(logfile) else: handler = logging.StreamHandler(sys.stdout) handler.setLevel(level) #handler.setFormatter(logging.Formatter()) logger.addHandler(handler) # In case the provided logger is in a sub-package... if logger is not _logger: configure_logger( _logger, verbosity, logfile=logfile, maxlevel=maxlevel, ) def hide_emit_errors(): """Ignore errors while emitting log entries. Rather than printing a message describing the error, we show nothing. """ # For now we simply ignore all exceptions. If we wanted to ignore # specific ones (e.g. BrokenPipeError) then we would need to use # a Handler subclass with a custom handleError() method. orig = logging.raiseExceptions logging.raiseExceptions = False def restore(): logging.raiseExceptions = orig return restore class Printer: def __init__(self, verbosity=VERBOSITY): self.verbosity = verbosity def info(self, *args, **kwargs): if self.verbosity < 3: return print(*args, **kwargs)