Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mark lazy mode deprecated and add logger.lazy() for lazy format value #1233

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions loguru/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ from typing import (
overload,
)

import typing_extensions

if sys.version_info >= (3, 6):
from typing import Awaitable
else:
Expand All @@ -47,6 +49,7 @@ else:

_T = TypeVar("_T")
_F = TypeVar("_F", bound=Callable[..., Any])
_P = typing_extensions.ParamSpec("_P")
ExcInfo = Tuple[Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]]

class _GeneratorContextManager(ContextManager[_T], Generic[_T]):
Expand Down Expand Up @@ -364,5 +367,7 @@ class Logger:
def log(__self, __level: Union[int, str], __message: Any) -> None: ... # noqa: N805
def start(self, *args: Any, **kwargs: Any) -> int: ...
def stop(self, *args: Any, **kwargs: Any) -> None: ...
@staticmethod
def lazy(fn: Callable[_P, Any], *args: _P.args, **kwargs: _P.kwargs) -> Any: ...

logger: Logger
32 changes: 31 additions & 1 deletion loguru/_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@
else:
from pathlib import PurePath as PathLike


Level = namedtuple("Level", ["name", "no", "color", "icon"]) # noqa: PYI024

start_time = aware_now()
Expand Down Expand Up @@ -234,6 +233,13 @@ class Logger:
"""

def __init__(self, core, exception, depth, record, lazy, colors, raw, capture, patchers, extra):
if lazy:
warnings.warn(
"lazy mode is deprecated, use `LazyValue` for deferred value",
stacklevel=2,
category=DeprecationWarning,
)

self._core = core
self._options = (exception, depth, record, lazy, colors, raw, capture, patchers, extra)

Expand Down Expand Up @@ -2137,3 +2143,27 @@ def stop(self, *args, **kwargs):
stacklevel=2,
)
return self.remove(*args, **kwargs)

@staticmethod
def lazy(fn, *args, **kwargs):
"""Make fn lazy evaluated.

For example, fn will only be called if debug level is enabled.

```python
logger.debug("hello {}", logger.lazy(fn, *...))
```
"""
return LazyValue(fn, *args, **kwargs)


class LazyValue:
__slots__ = ("args", "fn", "kwargs")

def __init__(self, fn, *args, **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)
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ filterwarnings = [
'error',
# Mixing threads and "fork()" is deprecated, but we need to test it anyway.
'ignore:.*use of fork\(\) may lead to deadlocks in the child.*:DeprecationWarning',
# deprecated message for users
'ignore:lazy mode is deprecated.*',
]
testpaths = ["tests"]

Expand Down
9 changes: 9 additions & 0 deletions tests/test_lazy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from loguru import logger


def test_lazy_value(writer):
logger_bound = logger.bind(a=0)
logger_bound.add(writer, format="{message}")
logger_bound.info("hello {}", logger.lazy(str, 1))

assert writer.read() == "hello 1\n"
2 changes: 2 additions & 0 deletions tests/test_type_hinting.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import sys

import mypy.api
import pytest


@pytest.mark.skipif(sys.version_info < (3, 6), reason="typing supported is added in py36")
def test_mypy_import():
# Check stub file is valid and can be imported by Mypy.
# There exist others tests in "typesafety" subfolder but they aren't compatible with Python 3.5.
Expand Down
Loading