[Python-ideas] easier lazy logging in stdlib ?

mak apuf makapuf2 at gmail.com
Wed May 15 11:37:28 EDT 2019

Hello all,

Let's consider logging.debug(expensive_function())

There are a few possibilities to run an expensive function when
logging only if the log is effectively output :

- eager formatting + calling by using fstrings or .format(expensive_func())
- formatting being done lazily by separating the log string from the
arguments (by using % syntax which is dated maybe)
- creating a Lazy object that calls expensive_func when calling its
__str__ method, but that it a bit cumbersome because you have to
provide a lazy class for each, that only work for string values and
the cost of creating Lazy is eager.
- checking logging.isEnabledFor(lvl) explicitely (but then the level
is displayed twice, in enabled_for and in logging.LEVEL)

Maybe we can integrate a form of lazy evaluation for simple logging.
Different options are :
a- just evaluate when an argument is callable (not bw compatible, what
if this is unexpected and has side effects)
b- provide a LazyFormatter that does the preceding for any "%s" or
"%d" arg when used
c- provide a callable as part of the logging arguments and provide a
"%*s or %*d" format string instead of %s and %d (by example) for
calling the function before embedding it
d- check if a parameter has a special method such as __lazy__ at render time
e- provide a Lazy class in logging module to wrap lazy logging idiom:

class Lazy :
    def __init__(self, callable, *args, **kwargs) :
      self.callable = callable

    def __lazy__(self) : return self.callable(*args, **kwargs)

and checking if an argument is of Lazy type (again the drawback is
that this eagerly instanciate this class)

I'd prefer b,c or d+e

any thoughts?


More information about the Python-ideas mailing list