# Make logging function kwargs explicit

**URL:** <https://discuss.python.org/t/make-logging-function-kwargs-explicit/67952>\
**Category:** Ideas\
**Tags:** logging\
**Created:** [October 15, 2024, 11:26am UTC](https://discuss.python.org/t/make-logging-function-kwargs-explicit/67952 "2024-10-15T11:26:41Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![timhoffm](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/timhoffm/32/19468_2.png) [@timhoffm](https://discuss.python.org/u/timhoffm)\
**Post date:** [October 15, 2024, 11:26am UTC](https://discuss.python.org/t/make-logging-function-kwargs-explicit/67952/1 "2024-10-15T11:26:41Z")

</div>

The current functions for creating log message (`info()`, `warning()`, …) takes \*\*kwargs. These are forwarded to `Logger._log()`:

> <https://github.com/python/cpython/blob/fcef3fc9a593e2aa868d23cf2d91c57d8bf60ac6/Lib/logging/ __init__.py#L1640>

Therefore, the effectively accepted kwargs are `exc_info=None, extra=None, stack_info=False, stacklevel=1`.

Having such a hidden signature is not user-friendly. I propose to write the optional parameters out explicitly already in the message creation functions, i.e.  
change

```python
def info(self, msg, *args, **kwargs)

```

to

```python
def info(self, msg, *args, exc_info=None, extra=None, stack_info=False, stacklevel=1)

```

This makes the signatures more clear to the user.

There may be a slight performance impact in passing around individual parameters, that are the defaults most of the time. - This would need investigation. The logging functions must stay cheap. If performance prevents this change, would ` __signature__ ` be an alternative to provide a more user-friendly signature?

---

<div class="post-metadata">

**Author:** ![EpicWink](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/epicwink/32/17968_2.png) [@EpicWink](https://discuss.python.org/u/EpicWink)\
**Post date:** [October 15, 2024, 12:16pm UTC](https://discuss.python.org/t/make-logging-function-kwargs-explicit/67952/2 "2024-10-15T12:16:12Z")

</div>

I suspect you’ll find in the wild custom implementations of `Logger.log` (or other methods down the chain, including of `LogRecord`) which use some extra keyword arguments (either pre-defined or generic). More investigation required.

---

<div class="post-metadata">

**Author:** ![timhoffm](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/timhoffm/32/19468_2.png) [@timhoffm](https://discuss.python.org/u/timhoffm)\
**Post date:** [October 15, 2024, 1:39pm UTC](https://discuss.python.org/t/make-logging-function-kwargs-explicit/67952/3 "2024-10-15T13:39:11Z")

</div>

I believe custom parameters are currently not possible. Everything runs through the private `Logger._log()` method mentioned above, which has fixed explicit parameter names. Unless somebody monkey-patches that, custom parameters cannot pass.

A user could reimplement `log()` to bypass `_log`, but the private method does all the logic, so that would be pretty wild.

Also, it would be possible to keep \*\*kwargs, but still pull out all known optional parameters. \*\*kwargs would then only be relevant for custom subclasses.

---

<div class="post-metadata">

**Author:** ![bschubert](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/bschubert/32/26920_2.png) [@bschubert](https://discuss.python.org/u/bschubert)\
**Post date:** [October 15, 2024, 2:56pm UTC](https://discuss.python.org/t/make-logging-function-kwargs-explicit/67952/4 "2024-10-15T14:56:38Z")

</div>

> [@timhoffm](#):
>
> Having such a hidden signature is not user-friendly. I propose to write the optional parameters out explicitly already in the message creation functions

I don’t think CPyrhon generally needs to worry about having user-friendly signatures for its internal implementations, since the _actual_ user-friendly signatures are kept in the docs (what the end users will typically see) and typeshed (what IDEs and static analysis tools will use). For what’s it’s worth, the typeshed signatures for those functions already include all the optional parameters:

> <https://github.com/python/typeshed/blob/main/stdlib/logging/ __init__.pyi#L141-L149>

---

<div class="post-metadata">

**Author:** ![timhoffm](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/timhoffm/32/19468_2.png) [@timhoffm](https://discuss.python.org/u/timhoffm)\
**Post date:** [October 15, 2024, 3:35pm UTC](https://discuss.python.org/t/make-logging-function-kwargs-explicit/67952/5 "2024-10-15T15:35:10Z")

</div>

IPython `logging.info?` and the python REPL `help(logging.info)` still only see \*\*kwargs.

---

<div class="post-metadata">

**Author:** ![pawamoy](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pawamoy/32/5811_2.png) [@pawamoy](https://discuss.python.org/u/pawamoy)\
**Post date:** [October 15, 2024, 10:13pm UTC](https://discuss.python.org/t/make-logging-function-kwargs-explicit/67952/6 "2024-10-15T22:13:24Z")

</div>

True.

```pycon
>>> import logging
>>> help(logging.info)
Help on function info in module logging:

info(msg, *args, **kwargs)
    Log a message with severity 'INFO' on the root logger. If the logger has
    no handlers, call basicConfig() to add a console handler with a pre-defined
    format.

```

---

<div class="post-metadata">

**Author:** ![gerardw](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/gerardw/32/8739_2.png) [@gerardw](https://discuss.python.org/u/gerardw)\
**Post date:** [October 16, 2024, 2:21pm UTC](https://discuss.python.org/t/make-logging-function-kwargs-explicit/67952/7 "2024-10-16T14:21:45Z")

</div>

Perhaps my work patterns are atypical, but docs and typeshed are not what I typically see. I typically see the code itself and / or the help output.

Is there any downside to this proposal?

---

<div class="post-metadata">

**Author:** ![MegaIng](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/megaing/32/16162_2.png) [@MegaIng](https://discuss.python.org/u/MegaIng)\
**Post date:** [October 16, 2024, 2:37pm UTC](https://discuss.python.org/t/make-logging-function-kwargs-explicit/67952/8 "2024-10-16T14:37:26Z")

</div>

Yes, more maintenance burden if any of these parameters ever get renamed, their defaults changed, they get type hints added, deprecated or new parameters get added. (technically it also has a performance cost I think, but it’s unlikely that this is ever going to be noticeable)

A better idea would be to properly add the ability to copy signatures from one callable to another in a typing-transparent way.

---

<div class="post-metadata">

**Author:** ![timhoffm](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/timhoffm/32/19468_2.png) [@timhoffm](https://discuss.python.org/u/timhoffm)\
**Post date:** [October 16, 2024, 9:27pm UTC](https://discuss.python.org/t/make-logging-function-kwargs-explicit/67952/9 "2024-10-16T21:27:44Z")

</div>

The problem I see with “copy signatures from one callable to another” is that not all of them are identical. We have

- `debug(msg, *args, **kwargs)` (and `critical`, `error`, `warning`, `info` with the same signature
- `log(lvl, msg, *args, **kwargs)`
- `_log(level, msg, args, exc_info=None, extra=None, stack_info=False, stacklevel=1)`

One can possibly make that work, but it would have to be a partial copy taking some parameters from `_log` and replacing `**kwargs` in the other functions. Is that complexity worth the trouble? Writing out the signatures manually is simple and explicit.

Alternatively, would `debug. __signature__ = Signature(...)` be an option? While ` __signature__ ` is currently not a stable and public API, we may be able to use it internally. The worst thing that can happen is that it gets changed in the future and we have to go back to the current state or use a different approach.

Is there really a substantial maintainance burden? It’s not too likely that the signatures will change. Most of the mentioned changes would be breaking API and given the high bar we have on those quite unlikely. Adding new parameters is conceivable though. If there’s really a change, modifying 5 places instead of one is not too troublesome. One should notice that there are related variants of these methods and can make a simple search/replace to update all. I believe actually changing the signatues will be negligable effort compared to the preceeding discussion on if and how a change should be made.

---

<div class="post-metadata">

**Author:** ![MegaIng](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/megaing/32/16162_2.png) [@MegaIng](https://discuss.python.org/u/MegaIng)\
**Post date:** [October 16, 2024, 9:44pm UTC](https://discuss.python.org/t/make-logging-function-kwargs-explicit/67952/10 "2024-10-16T21:44:17Z")

</div>

> [@timhoffm](#):
>
> I believe actually changing the signatues will be negligable effort compared to the preceeding discussion on if and how a change should be made.

It’s still not a zero cost change. And if we did this here it would also set a precedent for all other places where this is an issue, inside and outside of the stdlib, namely that we will not add a nice and generally useful API, instead please duplicate information (or in this case, write the names 10 extra times, and the defaults 5 extra time).

> [@timhoffm](#):
>
> Alternatively, would `debug. __signature__ = Signature(...)` be an option?

Maybe - it should be some option that is visible for both dynamic tools (check) and static tools (not check, but they could learn). But this is a topic that I don’t think we need to start another discussion about this here - I actually think that enough discussions about this have already happened that at this point someone needs to write a PEP making a concrete proposal.
