Issue 18750: '' % [1] doesn't fail (original) (raw)

Created on 2013-08-15 17:10 by asvetlov, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (12)
msg195263 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2013-08-15 17:10
I think this is a bug. Can be reproduced on all Pythons (from 2.6 to 3.4a). Maybe should be fixed for 3.4 only as backward incompatible change.
msg195268 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2013-08-15 18:14
What is it that doesn't fail? The expression in the title is the beginning of a triple quoted string with no closing triple quote. If you mean '' % [1] not falling, it has been that way forever (well, python2.4 is as far back as I can test), so if it is deemed worth changing it certainly should not be backported. I suspect it is some consequence of the C level similarities between lists and dicts, since '' % {} is supposed to not produce an error.
msg195269 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2013-08-15 18:18
I don't understand why str % list and str % dict behaves differently than str % int: >>> 'abc' % [1] 'abc' >>> 'abc' % ([1],) Traceback (most recent call last): File "", line 1, in TypeError: not all arguments converted during string formatting >>> 'abc' % 1 Traceback (most recent call last): File "", line 1, in TypeError: not all arguments converted during string formatting >>> 'abc' % {1:2} 'abc' >>> 'abc' % ({1:2},) Traceback (most recent call last): File "", line 1, in TypeError: not all arguments converted during string formatting
msg195272 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2013-08-15 18:34
haypo: str % dict is a feature: >>> "%(a)s" % {'a': 1, 'b': 2} '1'
msg195273 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2013-08-15 18:38
For dict it is correct from my perspective. "" % {'a': 'b'} tries to substitute format specs like "%(a)s" and does nothing if spec is not present. But list case like "" % [1] confuse me.
msg195281 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2013-08-15 19:48
Yes, I suspect you are right that that is a bug...and a long standing one :)
msg195309 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2013-08-16 04:04
Objects/unicodeobject.c has this, at line 14316: if (PyMapping_Check(args) && !PyTuple_Check(args) && !PyUnicode_Check(args)) ctx.dict = args; else ctx.dict = NULL; and later at line 14348: if (ctx.argidx < ctx.arglen && !ctx.dict) { PyErr_SetString(PyExc_TypeError, "not all arguments converted during string formatting"); goto onError; } Because list now returns true for PyMapping_Check, this code thinks the list is a dict and skips the error. There's some discussion of PyMapping_Check in issue 5945.
msg195326 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2013-08-16 13:24
Hmm. The linked issue says the PyMappingCheck behavior is new in Python3, but this problem exists in Python2 (back to 2.4 at least) as well. Perhaps it is a different bug in Python2.
msg195329 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2013-08-16 13:31
The code looks basically the same in 2.7, and there PyMapping_Check looks for __getitem__, so maybe issue 5945 is just incorrect in its analysis. In any event, I'm not sure this is worth fixing. There are lots of little corner cases that could be broken.
msg195629 - (view) Author: Giacomo Alzetta (bakuriu) Date: 2013-08-19 13:04
Note that the documentation for formatting with %, found here: http://docs.python.org/2/library/stdtypes.html#string-formatting-operations, states: """ If format requires a single argument, values may be a single non-tuple object. [5] Otherwise, values must be a tuple with exactly the number of items specified by the format string, or a single mapping object (for example, a dictionary).""" Note how it explicitly states that in an expression: format % value there are two different cases: - If format contains *exactly one* format specifier, then value can be any non-tuple item and it will be formatted as is. Otherwise, value MUST be either tuple or a mapping. In your example '' contains 0 format specifiers, hence you MUST use either a tuple or a dict. Any other object triggers "undefined behaviour"(in particular depending on whether the object define __geitem__ or not the formatting might or might not raise an exception etc.) AFAIK only few people know this, hence changing the code could potentially break a lot of code for apparently no reason. Since people should start to move to str.format instead of % this wart may not be worth fixing.
msg195656 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2013-08-19 18:52
> Since people should start to move to str.format instead of % this wart may not be worth fixing. >>> ''.format_map([1]) '' However I agree that this is not worth fixing.
msg196719 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2013-09-01 12:39
Ok. Close as won't fix. Please reopen if needed.
History
Date User Action Args
2022-04-11 14:57:49 admin set github: 62950
2013-09-01 12:39:11 asvetlov set status: open -> closedresolution: wont fixmessages: +
2013-08-19 18:52:27 serhiy.storchaka set nosy: + serhiy.storchakamessages: +
2013-08-19 13:04:45 bakuriu set nosy: + bakuriumessages: +
2013-08-16 13:31:06 eric.smith set messages: +
2013-08-16 13:24:28 r.david.murray set messages: +
2013-08-16 04:04:56 eric.smith set title: '' % [1] doens't fail -> '' % [1] doesn't fail
2013-08-16 04:04:02 eric.smith set nosy: + eric.smithmessages: +
2013-08-15 19:48:00 r.david.murray set messages: +
2013-08-15 18:38:05 asvetlov set messages: +
2013-08-15 18:34:53 r.david.murray set messages: +
2013-08-15 18🔞01 vstinner set nosy: + vstinnermessages: + title: ''' % [1] doens't fail -> '' % [1] doens't fail
2013-08-15 18:14:13 r.david.murray set nosy: + r.david.murraymessages: +
2013-08-15 17:10:56 asvetlov create