[Python-3000] Please don't kill the % operator...

Ron Adam rrr at ronadam.com
Fri Aug 17 23:03:59 CEST 2007



Eric Smith wrote:
> Ron Adam wrote:
>>
>> Martin v. Lo"wis wrote:
>>> Bill Janssen schrieb:
>>>>> I think most of these points are irrelevant. The curly braces are not
>>>>> just syntactic sugar, at least the opening brace is not; the digit
>>>>> is not syntactic sugar in the case of message translations.
>>>> Are there "computation of matching braces" problems here?
>>> I don't understand: AFAIK, the braces don't nest, so the closing
>>> brace just marks the end of the place holder (which in the printf
>>> format is defined by the type letter).
> 
>> So expressions like the following might be difficult to spell.
>>
>>       '{{foo}{bar}}'.format(foo='FOO', bar='BAR', FOOBAR = "Fred")
>>
>> This would probably produce an unmatched brace error on the first '}'.
> 
> Ah, I see.  I hadn't thought of that case.  You're correct, it gives an 
> error on the first '}'.  This is a case where allowing whitespace would 
> solve the problem, sort of like C++'s "< <" template issue (which I 
> think they've since addressed).  I'm not sure if it's worth doing, though:
> 
> '{ {foo}{bar} }'.format(foo='FOO', bar='BAR', FOOBAR = "Fred")
> 
> On second thought, that won't work.  For example, this currently doesn't 
> work:
> '{0[{foo}{bar}]}'.format({'FOOBAR': 'abc'}, foo='FOO', bar='BAR')
> KeyError: 'FOO'
> 
> I can't decide if that's a bug or not.

I think if we escaped the braces with '\' it will work nicer.

I used the following to test the idea and it seems to work and should 
convert to C without any trouble.  So to those who can say, would something 
like this be an ok solution?

     def vformat(self, format_string, args, kwargs):
         # Needs unused args check code.
         while 1:
             front, field, back = self._get_inner_field(format_string)
             if not field:
                 break
             key, sep, spec = field.partition(':')
             value = self.get_value(key, args, kwargs)
             result = self.format_field(value, spec)
             format_string = front + result + back
         return format_string.replace('\{', '{').replace('\}', '}')

     def _get_inner_field(self, s):
         # Get an inner most field from right to left.
         end = 0
         while end < len(s):
             if s[end] == '}' and not self._is_escaped(s, end, '}'):
                 break
             end += 1
         if end == len(s):
             return s, '', ''
         start = end - 1
         while start >= 0:
             if s[start] == '{' and not self._is_escaped(s, start, '{'):
                 break
             start -= 1
         if start < 0:
             raise(ValueError, "missmatched braces")
         return s[:start], s[start+1:end], s[end+1:]

     def _is_escaped(self, s, i, char):
         # Determine if the char is escaped with '\'.
         if s[i] != char or i == 0:
             return False
         i -= 1
         n = 0
         while i >= 0 and s[i] == '\\':
             n += 1
             i -= 1
         return n % 2 == 1






More information about the Python-3000 mailing list