Skip to content

Commit c7a6a10

Browse files
committed
Allow make_filtering_bound_logger to receive a str for level
fixes hynek#665
1 parent d43b2cb commit c7a6a10

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ You can find our backwards-compatibility policy [here](https://github.com/hynek/
3838
- `structlog.stdlib.recreate_defaults()` now also adds `structlog.stdlib.PositionalArgumentsFormatter`.
3939
In default native mode, this is done by the loggers at the edge.
4040

41+
- `structlog.make_filtering_bound_logger()` now also accepts a string for *min_level*.
42+
4143

4244
## Fixed
4345

src/structlog/_native.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
ERROR,
2323
INFO,
2424
LEVEL_TO_NAME,
25+
NAME_TO_LEVEL,
2526
NOTSET,
2627
WARNING,
2728
)
@@ -70,7 +71,9 @@ async def aexception(
7071
return runner
7172

7273

73-
def make_filtering_bound_logger(min_level: int) -> type[FilteringBoundLogger]:
74+
def make_filtering_bound_logger(
75+
min_level: int | str,
76+
) -> type[FilteringBoundLogger]:
7477
"""
7578
Create a new `FilteringBoundLogger` that only logs *min_level* or higher.
7679
@@ -103,12 +106,19 @@ def make_filtering_bound_logger(min_level: int) -> type[FilteringBoundLogger]:
103106
<https://docs.python.org/3/library/logging.html#levels>`_ for
104107
possible values.
105108
109+
If you pass a string, it must be one of: ``critical``, ``error``,
110+
``warning``, ``info``, ``debug``, ``notset`` (upper/lower case
111+
doesn't matter).
112+
106113
.. versionadded:: 20.2.0
107114
.. versionchanged:: 21.1.0 The returned loggers are now pickleable.
108115
.. versionadded:: 20.1.0 The ``log()`` method.
109116
.. versionadded:: 22.2.0
110117
Async variants ``alog()``, ``adebug()``, ``ainfo()``, and so forth.
118+
.. versionchanged:: 25.1.0 *min_level* can now be a string.
111119
"""
120+
if isinstance(min_level, str):
121+
min_level = NAME_TO_LEVEL[min_level.lower()]
112122

113123
return LEVEL_TO_FILTERING_LOGGER[min_level]
114124

tests/test_log_levels.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from structlog import make_filtering_bound_logger
1212
from structlog._log_levels import LEVEL_TO_NAME
13+
from structlog._native import _nop
1314
from structlog.contextvars import (
1415
bind_contextvars,
1516
clear_contextvars,
@@ -314,3 +315,12 @@ def test_log_percent(self, bl, cl):
314315
bl.info("hey %! %%!")
315316

316317
assert [("info", (), {"event": "hey %! %%!"})] == cl.calls
318+
319+
def test_log_level_str(self):
320+
"""
321+
*min_level* can be a string and the case doesn't matter.
322+
"""
323+
bl = make_filtering_bound_logger("wArNiNg")
324+
325+
assert bl.warning is not _nop
326+
assert bl.info is _nop

0 commit comments

Comments
 (0)