New submission from Ben Wolfson <wolf...@gmail.com>:

As near as I can make out from 
<http://docs.python.org/library/string.html#formatstrings>, the following 
should return the string "hi":

"{0[!]}".format({"!":"hi"})

We have a "{", followed by a field name, followed by a "}", the field name 
consisting of an arg_name, which is 0, a "[", an element index, and a "]". The 
element index, which the docs say may be any source character except "]", is 
here "!". And, according to the docs, "An expression of the form '.name' 
selects the named attribute using getattr(), while an expression of the form 
'[index]' does an index lookup using __getitem__()".

However, it doesn't work:
>>> "{0[!]}".format({"!":"hi"})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Missing ']' in format string

The same thing happens with other strings that are significant in other places 
in the string-formatting DSL:

>>> "{0[:]}".format({":":"hi"})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Missing ']' in format string

If there are more characters the error message changes:

>>> class spam:
...     def __getitem__(self, k): return "hi"
... 
>>> "{0[this works as expected]}".format(spam())
'hi'
>>> "{0[I love spam! it is very tasty.]}".format(spam())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: expected ':' after format specifier
>>> "{0[.]}".format(spam()) # periods are ok
'hi'
>>> "{0[although curly braces, }, are not square brackets, they also don't work 
>>> here]}".format(spam())

Right square brackets work fine, though:

>>> "{0[[]}".format(spam())
'hi'

The failure of the expected result with curly braces presumably indicates at 
least part of the cause of the other failures: namely, that they stem from 
supporting providing flags to one replacement field using another, as in 
"{1:<{0}}". Which is quite useful. But it obviously isn't universally supported 
in the case of index fields anyway:

>>> "{0[recursive {1[spam]}]}".format(spam(), spam())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Only '.' or '[' may follow ']' in format field specifier

(Note that this is a very strange error message itself, asis the following, but 
since one isn't, according to the grammar, allowed to include a "]" where I've 
got one *anyway*, perhaps that's to be expected:

>>> "{0[recursive {1[spam].lower} ]}".format(spam(), spam())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'lower} ]'

)

But, even if that would explain why one can't use a "{" in the index field, it 
wouldn't explain why one can't use a "!" or ":", since if those aren't already 
part of a replacement field, as indicated by some initial "{", they couldn't 
have the significance that they do when they *are* part of that field.

----------
components: Interpreter Core
messages: 135258
nosy: Ben.Wolfson
priority: normal
severity: normal
status: open
title: str.format parses replacement field incorrectly
versions: Python 2.6, Python 3.1

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue12014>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to