Skip to content

Commit

Permalink
Allow make_filtering_bound_logger to receive a str for level
Browse files Browse the repository at this point in the history
fixes #665
  • Loading branch information
hynek committed Jan 13, 2025
1 parent d43b2cb commit c7a6a10
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ You can find our backwards-compatibility policy [here](https://github.com/hynek/
- `structlog.stdlib.recreate_defaults()` now also adds `structlog.stdlib.PositionalArgumentsFormatter`.
In default native mode, this is done by the loggers at the edge.

- `structlog.make_filtering_bound_logger()` now also accepts a string for *min_level*.


## Fixed

Expand Down
12 changes: 11 additions & 1 deletion src/structlog/_native.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
ERROR,
INFO,
LEVEL_TO_NAME,
NAME_TO_LEVEL,
NOTSET,
WARNING,
)
Expand Down Expand Up @@ -70,7 +71,9 @@ async def aexception(
return runner


def make_filtering_bound_logger(min_level: int) -> type[FilteringBoundLogger]:
def make_filtering_bound_logger(
min_level: int | str,
) -> type[FilteringBoundLogger]:
"""
Create a new `FilteringBoundLogger` that only logs *min_level* or higher.
Expand Down Expand Up @@ -103,12 +106,19 @@ def make_filtering_bound_logger(min_level: int) -> type[FilteringBoundLogger]:
<https://docs.python.org/3/library/logging.html#levels>`_ for
possible values.
If you pass a string, it must be one of: ``critical``, ``error``,
``warning``, ``info``, ``debug``, ``notset`` (upper/lower case
doesn't matter).
.. versionadded:: 20.2.0
.. versionchanged:: 21.1.0 The returned loggers are now pickleable.
.. versionadded:: 20.1.0 The ``log()`` method.
.. versionadded:: 22.2.0
Async variants ``alog()``, ``adebug()``, ``ainfo()``, and so forth.
.. versionchanged:: 25.1.0 *min_level* can now be a string.
"""
if isinstance(min_level, str):
min_level = NAME_TO_LEVEL[min_level.lower()]

return LEVEL_TO_FILTERING_LOGGER[min_level]

Expand Down
10 changes: 10 additions & 0 deletions tests/test_log_levels.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from structlog import make_filtering_bound_logger
from structlog._log_levels import LEVEL_TO_NAME
from structlog._native import _nop
from structlog.contextvars import (
bind_contextvars,
clear_contextvars,
Expand Down Expand Up @@ -314,3 +315,12 @@ def test_log_percent(self, bl, cl):
bl.info("hey %! %%!")

assert [("info", (), {"event": "hey %! %%!"})] == cl.calls

def test_log_level_str(self):
"""
*min_level* can be a string and the case doesn't matter.
"""
bl = make_filtering_bound_logger("wArNiNg")

assert bl.warning is not _nop
assert bl.info is _nop

0 comments on commit c7a6a10

Please sign in to comment.