A format string with :
and /
present. When tried formatting with a value dict
it's throwing:
ValueError: Missing ']' in format string
Example:
In [312]: value
Out[312]: {'key:/key_part': 1}
In [313]: string_to_format
Out[313]: '{v[key:/key_part]}'
In [314]: string_to_format.format(v=SafeDict(value))
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-314-3ee97d9dfb86> in <module>()
----> 1 string_to_format.format(v=SafeDict(value))
ValueError: Missing ']' in format string
where SafeDict
is the implementation used from this SO answer.
In [311]: class SafeDict(dict):
...: def __missing__(self, key):
...: return "NULL"
Any ideas on how to get through this?
This is a known limitation of the basic parsing used in string formatting implementation. The section Simple and Compound Field Names in PEP 3101 describes 'getitem' support in str.format
syntax (emphasis mine):
An example of the 'getitem' syntax:
"My name is {0[name]}".format(dict(name='Fred'))
It should be noted that the use of 'getitem' within a format string is much more limited than its conventional usage. In the above example, the string 'name' really is the literal string 'name', not a variable named 'name'. The rules for parsing an item key are very simple. If it starts with a digit, then it is treated as a number, otherwise it is used as a string.
Because keys are not quote-delimited, it is not possible to specify arbitrary dictionary keys (e.g., the strings "10" or ":-]") from within a format string.
And later under the "Implementation note":
The
str.format()
function will have a minimalist parser which only attempts to figure out when it is "done" with an identifier (by finding a '.' or a ']', or '}', etc.).
So this a shortcoming of str.format
by design. The attentive reader may note that the OP's string formatting works in Python 3. Some edge cases were patched up in Python 3.4, yet the same issue is still present in Python 3.3 and below.
The relevant ticket was issue12014: str.format parses replacement field incorrectly. Since Python 2.7 is end-of-life now, the chances of getting those improvements from Python 3.4 backported to 2.7 are zero, so you will have to choose between two options: