[issue21547] '!s' formatting documentation bug

New submission from Joshua Landau:
In the docs for 2.x about the formatting syntax:
https://docs.python.org/2/library/string.html#format-string-syntax
it says
"Two conversion flags are currently supported: '!s' which calls str() on the value, and '!r' which calls repr()."
but for unicode formatters, '!s' calls unicode() instead.
See http://stackoverflow.com/questions/23773816/why-python-str-format-doesnt-cal... for the question that found this.
---------- assignee: docs@python components: Documentation messages: 218863 nosy: Joshua.Landau, docs@python priority: normal severity: normal status: open title: '!s' formatting documentation bug versions: Python 2.7
_______________________________________ Python tracker report@bugs.python.org http://bugs.python.org/issue21547 _______________________________________

Eric V. Smith added the comment:
I suggest using whatever language explains what "u'%s' %obj" does. It's the same behavior.
From the SO question, given:
class A(object): def __str__(self): return 'as str'
def __unicode__(self): return u'as unicode'
Then:
'%s' % A()
'as str'
u'%s' % A()
u'as unicode'
and:
'{!s}'.format(A())
'as str'
u'{!s}'.format(A())
u'as unicode'
---------- nosy: +eric.smith
_______________________________________ Python tracker report@bugs.python.org http://bugs.python.org/issue21547 _______________________________________

Steven Barker added the comment:
The behavior of !s with the format() methods isn't exactly the same as %s with % formatting. With the latter, the conversion depends on the type of the result string, which in turn depends on whether the format string *or any of the values values* is unicode:
>>> class X(): def __str__(self): return "str" def __unicode__(self): return u"unicode"
>>> "%s %s" % ("foo", X()) 'foo str' >>> "%s %s" % (u"foo", X()) u'foo unicode' >>> u"%s %s" % ("foo", X()) u'foo unicode' >>> u"%s %s" % (u"foo", X()) u'foo unicode'
The format methods are more consistent, always returning the same type as the format string regardless of the types of the arguments (and using the appropriate converter):
>>> "{} {!s}".format("foo", X()) 'foo str' >>> "{} {!s}".format(u"foo", X()) 'foo str' >>> u"{} {!s}".format("foo", X()) u'foo unicode' >>> u"{} {!s}".format(u"foo", X()) u'foo unicode'
The documentation for %s conversion (in the second table here: https://docs.python.org/2/library/stdtypes.html#string-formatting-operations ) also suggests that it always uses str(), though the footnote for that table entry alludes to the behavior shown above without ever mentioning using unicode() for conversions explicitly.
---------- nosy: +Steven.Barker
_______________________________________ Python tracker report@bugs.python.org http://bugs.python.org/issue21547 _______________________________________

Changes by Ezio Melotti ezio.melotti@gmail.com:
---------- nosy: +ezio.melotti type: -> behavior
_______________________________________ Python tracker report@bugs.python.org http://bugs.python.org/issue21547 _______________________________________

Serhiy Storchaka storchaka+cpython@gmail.com added the comment:
Python 2.7 is no longer supported.
---------- nosy: +serhiy.storchaka resolution: -> out of date stage: -> resolved status: open -> closed
_______________________________________ Python tracker report@bugs.python.org https://bugs.python.org/issue21547 _______________________________________
participants (5)
-
Eric V. Smith
-
Ezio Melotti
-
Joshua Landau
-
Serhiy Storchaka
-
Steven Barker