PEP8 compliant way to switch log for the whole package

I have a package with this structure:

mypackage
    |
    +---- a.py
    +---- b.py
    +---- __init__.py

      

this package is sometimes used as a library, sometimes interactively with IPython, so I need to set up the logging differently in both cases:

  • interactive: print logs to console, so loggers must have a handler StreamHandler

  • library: let the user customize the logging, so the loggers must have a handler NullHandler

In __init__.py

I do this:

import logging
import a
import b

logging.getLogger(__name__).addHandler(logging.NullHandler())    

def get_loggers():
    """
    Get all the logger objects instantiated for the current package
    """
    loggers = []
    for logger in logging.Logger.manager.loggerDict.values():
        if not isinstance(logger, logging.Logger):
            continue
        if logger.name.startswith(__name__):
            loggers.append(logger)
    return loggers


def enable_logs():
    """
    Configure loggers to print on stdout/stderr
    """
    handler = logging.StreamHandler()
    handler.setFormatter(logging.Formatter(
        '%(name)s :: %(levelname)s :: %(message)s'))
    for logger in get_loggers():
        logger.removeHandler(handler)
        logger.addHandler(handler)
        logger.setLevel(logging.DEBUG)
        logger.propagate = False


def disable_logs():
    """
    Configure loggers not to print anywhere
    """
    handler = logging.NullHandler()
    for logger in get_loggers():
        logger.removeHandler(handler)
        logger.addHandler(handler)
        logger.propagate = False

      

a.py

and b.py

start with:

import logging

log = logging.getLogger(__name__)
log.addHandler(logging.NullHandler())

      

So now I can enable / disable logging by doing the following:

import mypackage
mypackage.enable_logs()
mypackage.disable_logs()

      

But this solution does not match PEP8

, because in __init__.py

I import modules that are not used. Note that they don't need to import them, but I want to because then their respective registrars are created when the package is imported.

Question1: Is their PEP8 compliant way to achieve the same goal?

Question2: Is it subjective, maybe PEP8 in this case?

+3


source to share


1 answer


You can call this function at the beginning of your logs enable and disable functions to dynamically load modules, but I think the PEP traversal in this way might change:



import glob
import imp
import os

def load_modules(module_names=None):
    if module_names is None:
        cur_dir = os.path.realpath(os.path.dirname(__file__))
        module_wc = '{}/*.py'.format(cur_dir)
        module_names = [mn for mn in glob.glob(module_wc) if not mn.startswith('_')]
    modules = map(imp.load_source, module_names)
    return modules

      

+1


source







All Articles