classification
Title: %-formatting and dicts
Type: behavior Stage:
Components: Interpreter Core Versions: Python 3.1, Python 2.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: eric.smith Nosy List: ajaksu2, akuchling, anthonybaxter, benjamin.peterson, eric.smith, georg.brandl, hdiwan650, jafo, jimjjewett, lemburg, loewis, skip.montanaro (12)
Priority: low Keywords patch

Created on 2006-04-10 19:39 by lemburg, last changed 2009-04-27 15:15 by eric.smith.

Files
File name Uploaded Description Edit Remove
format.patch akuchling, 2006-07-25 12:35 Draft of approach (fixes string object only)
format-v2.patch jafo, 2007-08-25 20:15
Messages (19)
msg28186 - (view) Author: Marc-Andre Lemburg (lemburg) Date: 2006-04-10 19:39
This looks like a bug in the way the %-formatting code
works or is it a feature ?

>>> '%s %(a)s' % {'a': 'xyz'}
"{'a': 'xyz'} xyz"

>>> u'%s %(a)s' % {'a': 'xyz'}
u"{'a': 'xyz'} xyz"

Note that both strings and Unicode are affected.

Python 2.3 and 2.4 also show this behavior.

I would have expected an exception or the %-formatter
simply ignoring the first %s.


msg28187 - (view) Author: Hasan Diwan (hdiwan650) Date: 2006-04-14 08:33
Logged In: YES 
user_id=1185570

It looks as though it's a feature... The first %s will print
the whole dictionary as a string, the second, only that
value looked up by the key.
msg28188 - (view) Author: Georg Brandl (georg.brandl) Date: 2006-07-24 13:37
Logged In: YES 
user_id=849994

The library ref specifies that if a dict is supplied, the
format specifiers MUST include a mapping key, so the right
thing to do would be to raise an exception.

Is it worth breaking backwards compatibility, Martin?
msg28189 - (view) Author: Martin v. Löwis (loewis) Date: 2006-07-24 20:07
Logged In: YES 
user_id=21627

IMO, it's correct to break backwards compatibility, as the
current behaviour clearly violates the spec; I'm not sure
whether it's good to break the behaviour *now* (i.e. with no
further betas before the release of 2.5).

Deferring to the release manager.
msg28190 - (view) Author: A.M. Kuchling (akuchling) Date: 2006-07-25 12:35
Logged In: YES 
user_id=11375

So, what should '%s' % {} do?  Should it be 1) '{}' or 2) an
error because the argument is a mapping but the format
specifier doesn't have a '(key)'?

I've attached a draft patch that fixes stringobject.c; if
the approach is deemed OK, I'll apply it to unicodeobject.c,
too.  PyString_Format() records the type of argument being
processed (a tuple or a mapping) and raises ValueError if
you mix them, at the cost of two extra comparisons for each
format specifier processed.  This preserves the current
behaviour of '%s' % dictionary.

Questions: 1) is the approach reasonably clear?  2) are the
additional two comparisons unacceptably slow?  3) Is
ValueError the right exception?  4) can someone come up with
a better exception message than "both keyed and unkeyed
format specifiers used"?

msg28191 - (view) Author: Skip Montanaro (skip.montanaro) Date: 2006-08-04 13:21
Logged In: YES 
user_id=44345

Looks okay to me, though why is the FORMAT_TYPE_UNKNOWN test
necessary in the second case but not the first?
msg28192 - (view) Author: Marc-Andre Lemburg (lemburg) Date: 2006-08-04 13:26
Logged In: YES 
user_id=38388

The patch looks OK.

I'd make it a TypeError and use "cannot use positional and
named formatting parameters at the same time" as message.

Thanks.
msg28193 - (view) Author: Jim Jewett (jimjjewett) Date: 2006-08-18 22:01
Logged In: YES 
user_id=764593

Just a bit of encouragement for checking consistency like 
this; the explicit error message would have helped with a 
mistake I made earlier today.  For one of several keys, I 
mistyped it as "(%key)s", and a message about "not enough 
values" just didn't make sense.
msg28194 - (view) Author: Marc-Andre Lemburg (lemburg) Date: 2006-08-18 22:17
Logged In: YES 
user_id=38388

Should this patch be applied to the 2.5 branch ?

And if so, before or after the release of 2.5 ?
msg28195 - (view) Author: Georg Brandl (georg.brandl) Date: 2006-08-19 05:25
Logged In: YES 
user_id=849994

I'd say before 2.5 final...
msg28196 - (view) Author: Anthony Baxter (anthonybaxter) Date: 2007-01-12 09:10
I'm happy for this to be applied for 2.5.1. I don't have time to do it myself for a few days, though, so feel free to beat me to it.
msg28197 - (view) Author: A.M. Kuchling (akuchling) Date: 2007-01-12 14:57
The patch shouldn't be applied as it stands, though, because it's not complete; similiar changes need to be made to the Unicode type, for a start.

To answer Skip's question: I don't remember the logic of the format code.  I think the FORMAT_TYPE_UNKNOWN check may be unnecessary; the code could just always do format_type = _TUPLE, occasionally doing a redundant assignment (but who cares)?

I don't think I'll have any chance to work on this; PyCon is keeping me busy, and the mailbox bugs will take priority for me.
msg55292 - (view) Author: Sean Reifschneider (jafo) Date: 2007-08-25 20:15
I'm attaching a new version of this which includes AMK's string patch
ported over to unicode.

Any objections to my committing this to the trunk?  Should it also go in
for the next 2.5 release?
msg66798 - (view) Author: Georg Brandl (georg.brandl) Date: 2008-05-13 19:27
This probably won't be important anymore now that we have str.format()...
msg66801 - (view) Author: Marc-Andre Lemburg (lemburg) Date: 2008-05-13 20:06
Sean, why don't you just check in the patch ?

Then we can close the bug.

Georg, the fact that we have an alternative method for string formatting
doesn't mean that it's ok for Python to hide error using the prevailing
method of string formatting.
msg66802 - (view) Author: Georg Brandl (georg.brandl) Date: 2008-05-13 20:42
I didn't want to imply that, but seeing that nobody cared about it for
so long I hadn't much hope for the future... ;)
msg66813 - (view) Author: Marc-Andre Lemburg (lemburg) Date: 2008-05-14 09:39
I guess the patch was just forgotten after the 2.5 release was out.

I've added a 2.6 tag and assigned the patch to Sean.
msg86636 - (view) Author: Daniel Diniz (ajaksu2) Date: 2009-04-27 01:19
Confirmed in trunk and py3k. How about changing this for 3.1?
msg86671 - (view) Author: Eric Smith (eric.smith) Date: 2009-04-27 15:15
The patch incorrectly raises an exception for:
'%(a)s %%' % {'a':'xyz'}

I'll look into fixing it.
History
Date User Action Args
2009-04-27 15:15:19eric.smithsetmessages: + msg86671
2009-04-27 12:23:53eric.smithsetassignee: jafo -> eric.smith
versions: + Python 2.7, - Python 2.6
2009-04-27 01:19:26ajaksu2setversions: + Python 3.1, - Python 2.5
nosy: + ajaksu2, eric.smith, benjamin.peterson

messages: + msg86636

keywords: + patch
type: behavior
2008-05-14 09:39:36lemburgsetassignee: anthonybaxter -> jafo
messages: + msg66813
versions: + Python 2.6
2008-05-13 20:43:04georg.brandlsetmessages: + msg66802
2008-05-13 20:06:40lemburgsetmessages: + msg66801
2008-05-13 19:27:41georg.brandlsetpriority: normal -> low
messages: + msg66798
2007-08-30 16:55:28gvanrossumsetpriority: release blocker -> normal
2007-08-25 20:15:12jafosetfiles: + format-v2.patch
nosy: + jafo
messages: + msg55292
2006-04-10 19:39:08lemburgcreate