loguru
loguru copied to clipboard
improve lazy support
since we are using new style format, it's possible to control how value are formatted with __format__
current lazy option is not necessary, we can add a LazyValue type, this make is possible to mix lazy and un-lazy arguments
import logging
import sys
import time
from typing import Callable, Any, ParamSpec
from loguru import logger
logger.remove()
logger.add(sys.stderr, level="INFO")
P = ParamSpec("P")
class LazyValue:
__slots__ = ("fn", "args", "kwargs")
def __init__(self, fn: Callable[P, Any], *args: P.args, **kwargs: P.kwargs):
self.fn = fn
self.args = args
self.kwargs = kwargs
def __format__(self, format_spec: str):
return format(self.fn(*self.args, **self.kwargs), format_spec)
def expensive_func() -> int:
print("expensive_func called")
time.sleep(1)
return 1
def expensive_func_2(s: int) -> int:
print("expensive_func called")
time.sleep(s)
return 1
logger.debug("hello {} from {}", LazyValue(expensive_func), "Alice")
logger.info("hello {} from {}", LazyValue(expensive_func_2, 5), "Alice")
Nice! Wouldn't it be easier to just accept a supplier function (i.e. lambda: "Hello" or an object method None.__str__) to be evaluated instead of a custom class?
Nice! Wouldn't it be easier to just accept a supplier function (i.e.
lambda: "Hello"or an object methodNone.__str__) to be evaluated instead of a custom class?
I think that's very strange behavior for "formatting"
If anything, it already exists as an external library like lazy-string for example.
I agree it's more powerful than the current opt(lazy=True) design.
If anything, it already exists as an external library like
lazy-stringfor example.I agree it's more powerful than the current
opt(lazy=True)design.
it only support old style percent formatting, not new style {} formatting
from lazy_string import LazyString
from loguru import logger
def make_foo() -> int:
return 1
logger.info("nice, {:05d}".format(LazyString(make_foo)))
Traceback (most recent call last):
File "C:\Users\Trim21\proj\test\f.py", line 9, in <module>
logger.info("nice, {:05d}".format(LazyString(make_foo)))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: unsupported format string passed to LazyString.__format__
now we have https://peps.python.org/pep-0750/ , any new thoughts?