Created on 2017-02-15 14:53 by Jerry Dimitrov, last changed 2017-03-24 22:43 by xiang.zhang. This issue is now closed.
Hello everyone,
This is my first bug report to the python project, so please excuse me if the metadata for this particular issue is not 100% accurate.
Today I noticed (with the help from couple of people in IRC) a strange behavior in the python string formatting functionality.
Consider the following code snippets:
```
'%(a)s %(b)' % {'a': '1', 'b': '2'}
# result:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: incomplete format
```
```
'%(a) %(b)s' % {'a': '1', 'b': '2'}
# result:
'%(b)s'
# expected result:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: incomplete format
```
It seems that there is some kind of inconsistent (undefined) behavior, during the parsing of the type character for the formatted string (tested across all major python 2.x/3.x versions).
According to the documentation for string formatting and the relevant PEPs, there is no additional info about this particular case.
I want to say thank you to Yhg1s, JustASlacker, Jerub and lz1irq for discovering this 'bug/feature' and the additional information about it.
Please let me know if this is a bug, since I am not 100% sure if this is the case.
Thanks in advance for your time!
Best Regards,
Jerry
In this example characters between percents are parsed as for any conversion specifier but ignored and '%(a) %' is formatted to '%'. '(a)' specifies a mapping key, ' ' is a conversion flag, the second '%' is a conversion type.
>>> '%(a) d' % {'a': 123}
' 123'
>>> '%(a) %' % {'a': 123}
'%'
This behavior is explicable but looks weird and errorprone. I'm not sure about changing behavior in maintained branches (technically this may be not a bug), but I think it is worth to make this an error in the developed branch.
I don't think we should change the behavior in maintenance branches. I take it what you want to do is make it so that if the parser ends up thinking it is seeing '%%' but there is stuff between the two %s, that's an error?
Yes, it is what I want. Current behavior is just an artefact of the implementation. I have doubts that any other implementation of printf-like formatting has such behavior.
Bytes formatting starves from the same issue.
>>> b'% %' % {}
b'%'
But there are differences:
>>> '%12%' % ()
'%'
>>> b'%12%' % ()
b' %'
The documentation[1] explicitly states using % to do string format could be error-prone and recommends using str.format(). So +1 on no change in maintenance branches. [1] https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting
Or even not fix it in develop branch.
Here is a patch.
Thanks for the documentation reference. Can we at least add this link reference [1] as a note or something like that into those documentation sections: [2] https://docs.python.org/2/library/stdtypes.html#string-formatting and [3] https://docs.python.org/3/library/string.html#string-formatting I couldn't fine the printf specific documentation at first, so this is why I created the report. Regards, Jerry
New changeset 9f8ad3f39e0a92ed37d012b9dd237399524f0d51 by Xiang Zhang (Serhiy Storchaka) in branch 'master': bpo-29568: Disable any characters between two percents for escaped percent "%%" in the format string for classic string formatting. (GH-513) https://github.com/python/cpython/commit/9f8ad3f39e0a92ed37d012b9dd237399524f0d51
keywords:
+ patch
stage: patch review
messages:
+ msg287859
versions:
- Python 3.3, Python 3.4