This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: logging module cannot format str.format log messages
Type: enhancement Stage:
Components: Versions: Python 3.2
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: Nosy List: gkoller, kespindler, r.david.murray, vinay.sajip
Priority: normal Keywords: patch

Created on 2012-02-16 15:20 by gkoller, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
issue14031.patch kespindler, 2014-01-13 19:37
Messages (10)
msg153481 - (view) Author: Guido Kollerie (gkoller) Date: 2012-02-16 15:20
When logging messages with variable data one typically writes:

    username = 'Guido'
    logging.info('User %s logged in', username)

However Python 3 has support str.format (PEP 3101). If one has adopted str.format for formatting strings in Python 3 code one should also be able to write the above as:

    logging.info('User {} logged in', username)

However this currently is not supported. For backwards compatibility,% style logging should remain the default. However when a logger is configured using:

    import logging
    logging.basicConfig(style='{', format='{levelname}:{message}')

all subsequent calls to logging.debug, logging.info, logging.warning, logging.error, logging.critical, logging.exception and logging.log should use str.format for formatting.
msg153482 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2012-02-16 15:31
That can't work.  The logging messages may come from libraries written by someone else, using % formatting.  The style has to be set at the individual logger level.
msg153484 - (view) Author: Guido Kollerie (gkoller) Date: 2012-02-16 15:59
I see, could this be made to work if I explicitly request a logger instead?:

    logger = logging.getLogger('my_logger', style='{')
    logger.info('User {} logged in', username)

Maybe even for the root logger:

    root_logger = logging.getLogger(style='{')
    root_logger.info('User {} logged in', username)
msg153487 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2012-02-16 17:05
Use instead the approach described in this post:

http://plumberjack.blogspot.com/2010/10/supporting-alternative-formatting.html
msg208042 - (view) Author: (kespindler) Date: 2014-01-13 19:37
I came across this issue while fixing issue20242. This issue (14031) still exists and is a major source of annoyance and confusion, and I suggest re-opening it.

Specifying the "{" style, while still being forced to use % formatting in log statements is backward and incredibly confusing for a number of key reasons:

 - The `style` keyword accomplishes a single thing only, and that is changing the format specification of the output, which is specified once and never touched again. For the myriad log statements littered throughout a codebase, it has *absolutely* no effect.
 - This is incredibly misleading to users. Why would there be this parameter to basicConfig that does (next to) nothing? Furthermore, if I've specified the { style, **why** would I write my log statements using the % style.
 - It forces the user to keep using % style formatting. The documentation explicitly states that this is "old style" formatting, and "new style" should be used, (due to its many advantages). Why force the user to know two formatting styles?


I created a patch (with test cases) that allows for this functionality. The whole idea of this feature is giving users the choice, if their environment allows it, to use the new-style formatting. Users should not have to rely on the hack linked in the blog in order to achieve *exected* behavior!
msg208043 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2014-01-13 19:48
The reason is simple: in the general case you do not control all of the statements that produce log messages.  Some of them come from 3rd party library code.

Perhaps the documentation needs to be clarified on this point, and document the technique mentioned in the blog post Vinay linked to?  Or perhaps some pre-built wrappers can be provided in 3.5?
msg208045 - (view) Author: (kespindler) Date: 2014-01-13 20:03
I definitely do recognize that important case. I think the proper solution,
however, to that is make a very clear warning in the documentation that
changing the style might affect the logging of 3rd party tools. Those users
would probably have to use the % style formatting, which continues to work
exactly as always. I'd also note, this issue is largely related to the
`basicConfig` command. Anybody using significant 3rd party tools is likely
using a more complicated solution. In that case, this patch gives them the
flexibility to specify both LogRecords and the Formatter in whichever way
they desire.

The problem with leaving the behavior as is is that currently the style
keyword is effectively useless and grossly misleading to users.

Furthermore, the documentation makes reference to the ability to use new
style formats. From Logging HOWTO:

> As you can see, merging of variable data into the event description
message uses the old, %-style of string formatting. This is for backwards
compatibility: the logging package pre-dates newer formatting options such
as str.format() and string.Template. **These newer formatting options are
supported, but exploring them is outside the scope of this tutorial.**

This interpretation is the most logical interpretation of the style
keyword. Again, the format string is used once and is of comparative little
consequence - there's no real need for changing its format. Log messages
are written many, many times, and so it makes sense to allow the user to
write them in the modern format.

If the behavior really cannot be changed, this patch does provide
subclasses to LogRecord that give the desired behavior. Technically these
can be used independently of the style keyword.

On Mon, Jan 13, 2014 at 11:48 AM, R. David Murray <report@bugs.python.org>wrote:

>
> R. David Murray added the comment:
>
> The reason is simple: in the general case you do not control all of the
> statements that produce log messages.  Some of them come from 3rd party
> library code.
>
> Perhaps the documentation needs to be clarified on this point, and
> document the technique mentioned in the blog post Vinay linked to?  Or
> perhaps some pre-built wrappers can be provided in 3.5?
>
> ----------
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <http://bugs.python.org/issue14031>
> _______________________________________
>
msg208047 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2014-01-13 21:18
> The problem with leaving the behavior as is is that currently the
> style keyword is effectively useless and grossly misleading to users.

If you are referring to the style keyword in basicConfig, it merely sets the style of the Formatter used. That can certainly be made more explicit in the documentation.

There is a danger in assuming that you can associate a style with a LogRecord via a Logger, because there may be cases where a named logger is used by many different libraries (e.g. 'django.request' might be used by a number of Django middleware libraries). It may not be very common practice, but there is nothing preventing it.

The approach suggested also conflates the functionality of Formatters and Loggers, which could also be confusing.

> Users should not have to rely on the hack linked in the blog

I don't see what makes it a hack. Logging has allowed the usage of arbitrary objects (rather than just strings) for messages, from day one, by design, for this type of eventuality (amongst others).

> **These newer formatting options are supported, but exploring them
> is outside the scope of this tutorial.**

I will change this slightly by adding a cookbook recipe (based on the technique outlined in my blog post) and updating the above text to link to the cookbook recipe. I can also provide links from other parts of the documentation, where formatting is discussed, to point to the cookbook entry.
msg208168 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2014-01-15 15:12
Cookbook updated. See changesets 7c4f0c3dedaf and 0056aaf42bf7 for more information - docs.python.org should update within a day.
msg208348 - (view) Author: (kespindler) Date: 2014-01-17 17:09
Those new examples look good. I appreciate your revisiting the issue.

On Wed, Jan 15, 2014 at 7:12 AM, Vinay Sajip <report@bugs.python.org> wrote:

>
> Vinay Sajip added the comment:
>
> Cookbook updated. See changesets 7c4f0c3dedaf and 0056aaf42bf7 for more
> information - docs.python.org should update within a day.
>
> ----------
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <http://bugs.python.org/issue14031>
> _______________________________________
>
History
Date User Action Args
2022-04-11 14:57:26adminsetgithub: 58239
2014-01-17 17:09:57kespindlersetmessages: + msg208348
2014-01-15 15:12:29vinay.sajipsetmessages: + msg208168
2014-01-13 21:18:50vinay.sajipsetmessages: + msg208047
2014-01-13 20:03:43kespindlersetmessages: + msg208045
2014-01-13 19:48:13r.david.murraysetmessages: + msg208043
2014-01-13 19:37:01kespindlersetfiles: + issue14031.patch

nosy: + kespindler
messages: + msg208042

keywords: + patch
2012-02-16 17:05:42vinay.sajipsetstatus: open -> closed
resolution: out of date
messages: + msg153487
2012-02-16 15:59:46gkollersetmessages: + msg153484
2012-02-16 15:31:08r.david.murraysetnosy: + vinay.sajip, r.david.murray
messages: + msg153482
2012-02-16 15:20:48gkollercreate