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

Nick Coghlan ncoghlan at gmail.com
Wed Sep 30 07:48:32 CEST 2009


James Y Knight wrote:
> I'm resending a message I sent in June, since it seems the same thread
> has come up again, and I don't believe anybody actually responded
> (positively or negatively) to the suggestion back then.
> 
> http://mail.python.org/pipermail/python-dev/2009-June/090176.html
> 
> On Jun 21, 2009, at 5:40 PM, Eric Smith wrote:
>> I've basically come to accept that %-formatting can never go away,
>> unfortunately. There are too many places where %-formatting is used,
>> for example in logging Formatters. %-formatting either has to exist or
>> it has to be emulated.
> 
> It'd possibly be helpful if there were builtin objects which forced the
> format style to be either newstyle or oldstyle, independent of whether %
> or format was called on it.
> 
> E.g.
> x = newstyle_formatstr("{} {} {}")
> x % (1,2,3) == x.format(1,2,3) == "1 2 3"
> 
> and perhaps, for symmetry:
> y = oldstyle_formatstr("%s %s %s")
> y.format(1,2,3) == x % (1,2,3) == "1 2 3"
> 
> This allows the format string "style" decision is to be made external to
> the API actually calling the formatting function. Thus, it need not
> matter as much whether the logging API uses % or .format() internally --
> that only affects the *default* behavior when a bare string is passed in.
> 
> 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
> newstyle_formatstr() when necessary for passing to an API which uses %
> internally.
> 2) A long time later...deprecate str.__mod__; don't deprecate
> newstyle_formatstr.__mod__.
> 3) A while after that (maybe), remove str.__mod__ and replace all calls
> in Python to % (used as a formatting operator) with .format() so that
> the default is to use newstyle format strings for all APIs from then on.

I must have missed this suggestion when it went past the first time. I
certainly like this approach - it has the virtue of only having to solve
the problem once, and then application developers can use it to adapt
any existing use of %-mod formatting to str.format formatting.

Something like:

class formatstr(str):
  def __mod__(self, other):
    if isinstance(other, dict):
      return self.format(**dict)
    if isinstance(other, tuple)
      return self.format(*other)
    return self.format(other)

APIs that did their own parsing based on %-formatting codes would still
break, as would any that explicitly called "str" on the object (or
otherwise stripped the subclass away, such as via "'%s' % fmt"), but
most things should pass a string subclass through transparently.

I wouldn't bother with a deprecation plan for 'normal' %-formatting
though. I don't think it is going to be practical to actually get rid of
that short of creating Python 4.0.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
---------------------------------------------------------------


More information about the Python-Dev mailing list