[Python-Dev] transitioning from % to {} formatting (original) (raw)

James Y Knight foom at fuhm.net
Wed Sep 30 18:19:31 CEST 2009


On Sep 30, 2009, at 10:34 AM, Steven D'Aprano wrote:

E.g. x = newstyleformatstr("{} {} {}") x % (1,2,3) == x.format(1,2,3) == "1 2 3" Moving along, let's suppose the newstyleformatstr is introduced. What's the intention then? Do we go through the std lib and replace every call to (say) somestring % args with newstyleformatstr(somestring) % args instead? That seems terribly pointless to me

Indeed, that would be terribly pointless! Actually, more than
pointless, it would be broken, as you've changed the API from taking
oldstyle format strings to newstyle format strings.

That is not the suggestion. The intention is to change /nearly
nothing/ in the std lib, and yet allow users to use newstyle string
substitution with every API.

Many Python APIs (e.g. logging) currently take a %-type formatting
string. It cannot simply be changed to take a {}-type format string,
because of backwards compatibility concerns. Either a new API can be
added to every one of those functions/classes, or, a single API can be
added to inform those places to use newstyle format strings.

This could allow for a controlled switch towards the new format string format, with a long deprecation period for users to migrate:

1) introduce the above feature, and recommend in docs that people only ever use new-style format strings, wrapping the string in newstyleformatstr() when necessary for passing to an API which uses % internally. And how are people supposed to know what the API uses internally?

It's documented, (as it already must be, today!).

Personally, I think your chances of getting people to write: logging.Formatter(newstyleformatstr("%(asctime)s - %(name)s - % (level)s - %(msg)s")) instead of logging.Formatter("%(asctime)s - %(name)s - %(level)s - %(msg)s")

That's not my proposal.

The user could write either: logging.Formatter("%(asctime)s - %(name)s - %(level)s - %(msg)s") (as always -- that can't be changed without a long deprecation
period), or: logging.Formatter(newstyle_formatstr("{asctime} - {name} - {level} -
{msg}")

This despite the fact that logging has not been changed to use {}- style formatting internally. It should continue to call "self._fmt %
record.dict" for backward compatibility.

That's not to say that this proposal would allow no work to be done to
check the stdlib for issues. The Logging module presents one: it
checks if the format string contains "%{asctime}" to see if it should
bother to calculate the time. That of course would need to be changed.
Best would be to stick an instance which lazily generates its string
representation into the dict. The other APIs mentioned on this thread
(BaseHTTPServer, email.generator) will work immediately without
changes, however.

James



More information about the Python-Dev mailing list