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

Steven Bethard steven.bethard at gmail.com
Sat Oct 3 17:41:36 CEST 2009


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

* 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?

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

Steve
-- 
Where did you get that preposterous hypothesis?
Did Steve tell you that?
        --- The Hiphopopotamus


More information about the Python-Dev mailing list