diff -r aba7d1f2d2a9 Lib/test/test_unicode.py --- a/Lib/test/test_unicode.py Fri May 06 18:49:52 2011 +0200 +++ b/Lib/test/test_unicode.py Tue May 10 15:06:44 2011 -0700 @@ -550,6 +550,8 @@ self.assertEqual("{0[foo-bar]}".format({'foo-bar':'baz'}), 'baz') self.assertEqual("{0[foo bar]}".format({'foo bar':'baz'}), 'baz') self.assertEqual("{0[ ]}".format({' ':3}), '3') + self.assertEqual("{0[{]}".format({'{':3}), '3') + self.assertEqual("{0[!]}".format({'!':3}), '3') self.assertEqual('{foo._x}'.format(foo=C(20)), '20') self.assertEqual('{1}{0}'.format(D(10), D(20)), '2010') diff -r aba7d1f2d2a9 Objects/stringlib/string_format.h --- a/Objects/stringlib/string_format.h Fri May 06 18:49:52 2011 +0200 +++ b/Objects/stringlib/string_format.h Tue May 10 15:06:44 2011 -0700 @@ -628,6 +628,37 @@ return ok; } + +void +advance_beyond_field(SubString *str) +{ + if (str->ptr > str->end) return; + switch (*++str->ptr) { + case '[': + while(str->ptr < str->end && *(str->ptr) != ']') + str->ptr++; + advance_beyond_field(str); + break; + case '.': + while(str->ptr < str->end) + switch(*++str->ptr) { + case ':': + case '!': + str->ptr--; + return; + case '[': + advance_beyond_field(str); + str->ptr--; + break; + default: + continue; + } + break; + default: + return; + } +} + static int parse_field(SubString *str, SubString *field_name, SubString *format_spec, STRINGLIB_CHAR *conversion) @@ -647,6 +678,11 @@ field_name->ptr = str->ptr; while (str->ptr < str->end) { switch (c = *(str->ptr++)) { + case '.': + case '[': + str->ptr -= 2; + advance_beyond_field(str); + continue; case ':': case '!': break; @@ -726,6 +762,7 @@ STRINGLIB_CHAR c = 0; STRINGLIB_CHAR *start; int count; + int bracket_significant = 1; Py_ssize_t len; int markup_follows = 0; @@ -806,6 +843,17 @@ about that case */ while (self->str.ptr < self->str.end) { switch (c = *(self->str.ptr++)) { + case '[': + if (bracket_significant) { + while (self->str.ptr < self->str.end-1 && *self->str.ptr != ']') { + self->str.ptr++; + } + } + continue; + case ':': + case '!': + bracket_significant = 0; + continue; case '{': /* the format spec needs to be recursively expanded. this is an optimization, and not strictly needed */