[Python-3000] PEP 3101 Updated
Ron Adam
rrr at ronadam.com
Thu Aug 23 07:31:04 CEST 2007
Eric Smith wrote:
> Ron Adam wrote:
>>
>>
>> Eric Smith wrote:
>>> Ron Adam wrote:
>>>>> I've been re-reading the PEP, in an effort to make sure everything
>>>>> is working. I realized that these tests should not pass. The PEP
>>>>> says that "Format specifiers can themselves contain replacement
>>>>> fields". The tests above have replacement fields in the field
>>>>> name, which is not allowed. I'm going to remove this functionality.
>>>>>
>>>>> I believe the intent is to support a replacement for:
>>>>> "%.*s" % (4, 'how now brown cow')
>>>>>
>>>>> Which would be:
>>>>> "{0:.{1}}".format('how now brown cow', 4)
>>>>>
>>>>> For this, there's no need for replacement on field name. I've
>>>>> taken it out of the code, and made these tests in to errors.
>>>>
>>>> I think it should work myself, but it could be added back in later
>>>> if there is a need to.
>>>>
>>>>
>>>> I'm still concerned about the choice of {{ and }} as escaped brackets.
>>>>
>>>> What does the following do?
>>>>
>>>>
>>>> "{0:{{^{1}}".format('Python', '12')
>>>
>>> >>> "{0:{{^{1}}".format('Python', '12')
>>> Traceback (most recent call last):
>>> File "<stdin>", line 1, in <module>
>>> ValueError: unterminated replacement field
>>
>> When are the "{{" and "}}" escape characters replaced with '{' and '}'?
>
> While parsing for the starting '{'. I'm not saying this is the best or
> only or even PEP-specified way of doing it, but that's how the sample
> implementation does it (and the way the sandbox version has done it for
> many months).
Any problems can be fixed of course once the desired behavior is decided
on. These are just some loose ends that still need to be spelled out in
the PEP.
>>> But,
>>> >>> "{{{0:^{1}}".format('Python', '12')
>>> '{ Python '
>>
>> So escaping '{' with '{{' and '}' with '}}' doesn't work inside of
>> format expressions?
>
> As I have it implemented, yes.
>
>> That would mean there is no way to pass a brace to a __format__ method.
>
> No way using string.format, correct. You could pass it in using the
> builtin format(), or by calling __format__ directly. But you're
> correct, for the most part if string.format doesn't accept it, it's not
> practical.
See the suggestions below.
>>>> "{0}".format('{value:{{^{width}}', width='10', value='Python')
>>>
>>> >>> "{0}".format('{value:{{^{width}}', width='10', value='Python')
>>> '{value:{{^{width}}'
>>
>> Depending on weather or not the evaluation is recursive this may or
>> may not be correct.
>>
>> I think it's actually easier to do it recursively and not put limits
>> on where format specifiers can be used or not.
>
> But then you'd always have to worry that some replaced string looks like
> something that could be interpreted as a field, even if that's not what
> you want.
>
> What if "{value}" came from user supplied input? I don't think you'd
> want (or expect) any string you output that contains braces to be expanded.
Ok, after thinking about it for a while...
Then maybe it's best not to use any recursion, not even at the top level.
The above expressions would then need to spelled:
"{{0:.{0}}}".format(4).format('how now brown cow')
"{{value:^{width}}}".format(width='10').format(value='Python')
"{{0:{{^{0}}}".format(12).format('Python')
Do those work?
This is not that different to how '%' formatting already works.
Either way I'd like to see an unambiguous escapes used for braces. For
both ease of implementation and ease of reading. Maybe we can re-use the
'%' for escaping characters. ['%%', '%{', '%}']
"%{0:.{0}%}".format('4').format('how now brown cow')
"%{value:^{width}%}".format(width='10').format(value='Python')
"%{0:%%%{^{0}%}".format('12').format('Python')
The only draw back of this is the '%' specifier type needs to be expressed
as either '%%' or maybe by another letter, 'p'? Which is a minor issue I
think.
Reasons for doing this...
- It makes determining where fields start and stop easier than
using '{{' and '}}' when other braces are in the string.
(Both for humans and for code.)
- It's a better alternative than '\{' and '\}' because it doesn't
have any issues with back slashes and raw strings or cause
excessive '\'s in strings.
- It doesn't collide with regular expressions.
- It looks familiar in the context that it's used in.
- Everyone is already familiar with '%%'. So adding '%{' and '%}'
would not seem out of place.
Although a recursive solution is neat and doesn't require typing '.format'
as much, these two suggestions together are easy to understand and avoid
all of the above issues. (As near as I can tell.)
Cheers,
_RON
More information about the Python-3000
mailing list