This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: '!s' formatting documentation bug
Type: behavior Stage: resolved
Components: Documentation Versions: Python 2.7
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: docs@python Nosy List: Joshua.Landau, Steven.Barker, docs@python, eric.smith, ezio.melotti, serhiy.storchaka
Priority: normal Keywords:

Created on 2014-05-21 06:39 by Joshua.Landau, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (4)
msg218863 - (view) Author: Joshua Landau (Joshua.Landau) * Date: 2014-05-21 06:39
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-call-str for the question that found this.
msg218876 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2014-05-21 14:21
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'
msg218890 - (view) Author: Steven Barker (Steven.Barker) * Date: 2014-05-22 01:43
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.
msg370438 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2020-05-31 13:09
Python 2.7 is no longer supported.
History
Date User Action Args
2022-04-11 14:58:03adminsetgithub: 65746
2020-05-31 13:09:37serhiy.storchakasetstatus: open -> closed

nosy: + serhiy.storchaka
messages: + msg370438

resolution: out of date
stage: resolved
2014-06-02 18:19:55ezio.melottisetnosy: + ezio.melotti
type: behavior
2014-05-22 01:43:02Steven.Barkersetnosy: + Steven.Barker
messages: + msg218890
2014-05-21 14:21:36eric.smithsetnosy: + eric.smith
messages: + msg218876
2014-05-21 06:39:19Joshua.Landaucreate