[Python-Dev] summary of transitioning from % to {} formatting

MRAB python at mrabarnett.plus.com
Sat Oct 3 19:02:52 CEST 2009


Steven Bethard wrote:
> I thought it might be useful for those who don't have time to read a
> million posts to have a summary of what's happened in the formatting
> discussion.
> 
> The basic problem is that many APIs in the standard library and
> elsewhere support only %-formatting and not {}-formatting, e.g.
> logging.Formatter accepts::
>   logging.Formatter(fmt="%(asctime)s - %(name)s")
> but not::
>   logging.Formatter(fmt="{asctime} - {name}")
> 
> There seems to be mostly agreement that these APIs should at least
> support both formatting styles, and a sizable group (including Guido)
> believe that %-formatting should eventually be phased out (e.g. by
> Python 4). There are a number of competing proposals on how to allow
> such APIs to start accepting {}-format strings:
> 
> * Add a parameter which declares the type of format string::
>     logging.Formatter(fmt="{asctime} - {name}", format=BRACES)
>   The API code would then switch between %-format and {}-format
>   based on the value of that parameter. If %-formatting is to be
>   deprecated, this could be done by first deprecating
>   format=PERCENTS and requiring format=BRACES, and then changing the
>   default to format=BRACES.
> 
> * Create string subclasses which convert % use to .format calls::
>     __ = brace_fmt
>     logging.Formatter(fmt=__("{asctime} - {name}"))
>   The API code wouldn't have to change at all at first, as applying
>   % to brace_fmt objects would call .format() instead. If
>   %-formatting is to be deprecated, this could be done by first
>   deprecating plain strings and requiring brace_fmt strings, and
>   then allowing plain strings again but assuming they are {}-format
>   strings.
> 
> * Teach the API to accept callables as well as strings::
>     logging.Formatter(fmt="{asctime} - {name}".format)
>   The API code would just call the object with .format() style
>   arguments if a callable was given instead of a string. If
>   %-formatting is to be deprecated, this could be done by first
>   deprecating plain strings and requiring callables, and then
>   allowing plain strings again but assuming they are {}-format
>   strings
> 
I'm not keen on deprecating strings in favour of callables and then
callables in favour of strings.

> * Create translators between %-format and {}-format::
>     assert to_braces("%(asctime)s") == "{asctime}"
>     assert to_percents("{asctime}") == "%(asctime)s"
>   these could then either be used outside of the API::
>     logging.Formatter(fmt=to_percents("{asctime} - {name}"))
>   or they could be used within the API combined with some sort of
>   heuristic for guessing whether a {}-format string or a %-format
>   string was passed in::
>     logging.Formatter(fmt="{asctime} - {name}")
>   If %-formatting is to be deprecated, the transition strategy here
>   is trivial. However, no one has yet written translators, and it is
>   not clear what heuristics should be used, e.g. should the method
>   just try %-formatting first and then {}-formatting if it fails?
> 
Another possibility:

A StringFormat class with subclasses PercentStringFormat, 
BraceStringFormat, and perhaps DollarStringFormat.

Or:

A StringFormat class with methods parse_percent_format,
parse_brace_format, and parse_dollar_format. There could also be a
format-guesser method.

> I don't think there is consensus yet on which of these proposals
> should be the "blessed" one.
> 



More information about the Python-Dev mailing list