On Tue, May 15, 2018 at 04:23:26PM -0400, Eric V. Smith wrote: > I'm busy at the sprints, so I don't have a lot of time to think about this. > > However, let me just say that recursive format specs are supported, > to a depth of 1. > > >>> width=10 > >>> f'{"test":{width}}' > 'test ' > > So first the string is basically expanded to: > f'{"test":10}' > Then the string is formatted again to produce the final result. > > That is why the braces must match: they're being used for recursive > format specs. There's no mechanism for having braces that aren't > inspected by the f-string machinery. > > Eric
Eric, You say that recursive format specs are supported to a depth of 1, but it does not seem like true recursion to me. If it were true recursion, wouldn't the escaped braces be interpreted properly inside the format spec, just as they are in the literal portion of the f-string? Is there some reason why escaped braces are not supported in the format specs? Consider the following example: >>> class myclass: ... def __format__(self, fmt_spec): ... return 'fmt_spec: ' + fmt_spec >>> d = myclass() >>> x = 3 >>> print('1: ext={{x}} {d:int={{x}}}'.format(d=d)) 1: ext={x} fmt_spec: int={x} >>> print(f'2: ext={{x}} {d:int={{x}}}') 2: ext={x} fmt_spec: int={3} >>> print(f'3: ext={set([x])} {d:int={set([x])}}') 3: ext={3} fmt_spec: int={3} In each case, the same substring is found in the literal portion (ext) of the format string and in the format spec (int). In case 1, the format string is passed to a format method and the substring is {{x}}. In both cases, the double braces are interpreted as escaped braces, and both are converted to '{x}' in the final printed result. In case 2, the format string is an f string. The substring is still {{x}}. The first instance of {{x}} is found in the literal portion of the format string and the double braces are interpreted as escaped braces. It expands to {x} like in the first case. However, the second instance is found in the format spec, and this case the outer braces are stripped off and what is left over is treated as a Python expression. Here {x} is treated as a set literal containing one value, x. Since x is 3, the value of int is {3}. Case 3 confirms the interpretation of case 2 by simply replacing {x} with an alternate way of specifying a set literal that contains a single value. In this case there are no double braces and so both instances are treated the same, both expand to {3}. So the format method supports escaped braces in both the literal part of the format string and the format spec. f-strings supports escaped braces in the literal part of the format string, but in the format spec the outer level of braces are stripped off and what remains is interpreted as a Python expression. Is there some benefit to this difference? -Ken _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/