Title: Documentation on old-style formatting of dicts is overly restrictive
Type: Stage: resolved
Components: Documentation Versions: Python 2.7
Status: closed Resolution: duplicate
Dependencies: Superseder: %-formatting and dicts
View: 1467929
Assigned To: docs@python Nosy List: Ken.Basye, docs@python, eric.smith, r.david.murray
Priority: normal Keywords:

Created on 2010-09-08 22:08 by Ken.Basye, last changed 2010-09-09 15:29 by r.david.murray. This issue is now closed.

Messages (5)
msg115907 - (view) Author: Ken Basye (Ken.Basye) Date: 2010-09-08 22:08
From :

"When the right argument is a dictionary (or other mapping type), then the formats in the string must include a parenthesised mapping key into that dictionary inserted immediately after the '%' character."  
(with emphasis on 'must' in the HTML, BTW).  

This isn't correct:  "%s" % dict() is a perfectly legal expression with a dictionary as the right argument and no mapping key in the formats.  Indeed, if the current doc were correct, there would apparently be no way to format an empty dictionary.

How about this one-word fix:

"When the right argument is a dictionary (or other mapping type), then the formats in the string may include ..." and so on into the next sentence, and no emphasis on 'may'.

P.S. Not sure about the Type of this issue, and it's present in both 2.7 and current 3.X doc.
msg115910 - (view) Author: Ken Basye (Ken.Basye) Date: 2010-09-08 22:28
If someone's going to fix this, perhaps they might consider also adding the following clarification sentence after 'The mapping key selects the value to be formatted from the mapping.'  

The mapping key is interpreted as a string; a key error is raised if the dictionary does not have a matching string key. 

I don't think it's worth adding it, but consider this example:
>>> d = {2:2, '2':'two'}
>>> '%(2)s' % d
msg115924 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-09-09 02:15
Python 3.2a2+ (py3k:84613, Sep  7 2010, 19:17:31) 
[GCC 4.4.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> "%s %(abc)s" % dict(abc=2)
"{'abc': 2} 2"

I did not expect this result.  Looks like a bug to me.

>>> "%s %(abc)s" % (dict(abc=2), 4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: format requires a mapping
>>> "%d %(abc)s" % dict(abc=2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: %d format: a number is required, not dict
>>> "%s %s %(abc)s" % dict(abc=2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string

So, the only case which "works" (but is arguably buggy) is a single %s mixed in with dict lookups.  'may' does not adequately describe this reality.  'must' is much closer.  If it weren't a backward incompatible change I'd suggest making a single dict (i.e.: non-tuple) argument to % with non-dict-lookup patterns an error.  As it is, we'll just live with the quirk, and probably with the bug as well.

I'm not sure it is worth explaining all these quirks in the main docs.  Perhaps in a footnote?
msg115926 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2010-09-09 02:32
I think this might be a dupe of issue 1467929.
msg115949 - (view) Author: Ken Basye (Ken.Basye) Date: 2010-09-09 14:33
I think Eric is correct; it's a dupe.  And I was wrong about not otherwise being able to format an empty dictionary - "%s" % (d,) will always work and is arguably the right thing to do anyway.
Date User Action Args
2010-09-09 15:29:46r.david.murraysetstatus: open -> closed
resolution: duplicate
superseder: %-formatting and dicts
stage: needs patch -> resolved
2010-09-09 14:33:09Ken.Basyesettype: behavior ->
messages: + msg115949
versions: - Python 3.1, Python 3.2
2010-09-09 02:32:38eric.smithsetmessages: + msg115926
2010-09-09 02:15:36r.david.murraysetversions: + Python 3.1, Python 3.2
nosy: + r.david.murray

messages: + msg115924

type: behavior
stage: needs patch
2010-09-08 22:56:40eric.smithsetnosy: + eric.smith
2010-09-08 22:28:58Ken.Basyesetmessages: + msg115910
2010-09-08 22:08:36Ken.Basyecreate