diff --git a/docs/bound-loggers.md b/docs/bound-loggers.md index 0a6c3593..7b8601c4 100644 --- a/docs/bound-loggers.md +++ b/docs/bound-loggers.md @@ -82,7 +82,7 @@ Now `log` is a *bound logger* of type {class}`~structlog.typing.FilteringBoundLo Now if you call `log.info("Hello, %s!", "world", number=42)` the following happens: -1. `"world"` gets interpolated into `"Hello, %s!"`, making the event "Hello, world!". +1. `"world"` gets interpolated into `"Hello, %s!"`, making the event "Hello, world!"[^interpolation]. 2. The *bound logger*'s context gets copied and the key-value pairs from the `info` call are added to it. It becomes an *event dict* and is `{"foo": "bar", "number": 42}` now. 3. The event from step 1 is added too. @@ -99,6 +99,7 @@ Now if you call `log.info("Hello, %s!", "world", number=42)` the following happe By replacing the last processor, you decide on the **format** of your logs. For example, if you wanted JSON logs, you just have to replace the last processor with {class}`structlog.processors.JSONRenderer`. +[^interpolation]: String interpolation only takes place if you pass positional arguments. (filtering)= diff --git a/src/structlog/typing.py b/src/structlog/typing.py index 8cec1a54..d27625a9 100644 --- a/src/structlog/typing.py +++ b/src/structlog/typing.py @@ -155,6 +155,9 @@ class FilteringBoundLogger(BindableLogger, Protocol): String interpolation using positional arguments. .. versionadded:: 22.2.0 Async variants ``alog()``, ``adebug()``, ``ainfo()``, and so forth. + .. versionchanged:: 22.3.0 + String interpolation is only attempted if positional arguments are + passed. """ def bind(self, **new_values: Any) -> FilteringBoundLogger: