[Python-ideas] Let’s make escaping in f-literals impossible

Terry Reedy tjreedy at udel.edu
Fri Aug 19 01:07:58 EDT 2016


On 8/18/2016 3:30 PM, Steve Dower wrote:
> On 18Aug2016 1215, Terry Reedy wrote:
>> On 8/18/2016 12:50 PM, Steve Dower wrote:
>>> I don't think f'{x.partition('-')[0]}' is any less readable as a result
>>> of the reused quotes,

Why are you reusing the single quote', which needs the escaping that you 
don't like, instead of any of at least 6 alternatives that do not need 
any escaping?

f'{x.partition("-")[0]}'
f'{x.partition("""-""")[0]}'
f"{x.partition('-')[0]}"
f'''{x.partition('-')[0]}'''
f"""{x.partition('-')[0]}"""
f"""{x.partition('''-''')[0]}"""

It seems to me that that this is at least somewhat a strawman issue.

If you want to prohibit backslashed quote reuse in expressions, as in 
f'{x.partition(\'-\')[0]}', that is okay with me, as this is 
unnecessary* and arguably bad.  The third alternative above is better. 
What breaks colorizers, and what I therefore object to, is the 
innovation of adding magical escaping of ' or " without \.

Or add a new style rule to PEP 8.

F-strings: avoid unnecessary escaping in the expression part of f-strings.
Good: f"{x.partition('-')[0]}"
Bad: f'{x.partition(\'-\')[0]}'

Then PEP-8 checkers will flag such usage.

*I am sure that there are possible complex expressions that would be 
prohibited by the rule that would be otherwise possible.  But they 
should be extremely rare and possibly not the best solution anyway.

>> I find it hard to not read f'{x.partition(' + ')[0]}' as string
>> concatenation.

> That's a fair counter-example. Though f'{x.partition(\' + \')[0]}' still
> reads like string concatenation to me at first glance. YMMV.

When the outer and inner quotes are no longer the same, the effect is 
greatly diminished if not eliminated.

>>> and it will certainly be easier for highlighters
>>> to handle (assuming they're doing anything more complicated than simply
>>> displaying the entire expression in a different colour).
>>
>> Without the escapes, existing f-unaware highlighters like IDLE's will be
>> broken in that they will highlight the single f-string as two strings
>> with differently highlighted content in the middle.  For
>> f'{x.partition('if')[0]}', the 'if' is and will be erroneously
>> highlighted as a keyword.  I consider this breakage unacceptible.
>
> Won't it be broken anyway because of the new prefix?

No.  IDLE currently handles f-strings just fine other than not coloring 
the 'f'. This is a minor issue and easily fixed by adding '|f' and if 
allowed, '|F' at the end of the current stringprefix re.

> I'm sure there's a fairly straightforward way for a regex to say that a
> closing quote must not be preceded immediately by a backslash or by an
> open brace at all without a closing brace in between.

I do not know that this is possible.
Here is IDLE's current re for an unprefixed single quoted string.
    r"'[^'\\\n]*(\\.[^'\\\n]*)*'?"
The close quote is optional because it must match a string that is in 
the process of being typed and is not yet closed.  I consider providing 
a tested augmented re to be required for this proposal.

Even then, making the parsing out of strings in Python code for 
colorizing version dependent is a problem in itself for colorizers not 
tied to a particular x.y version.  Leaving prefixes aside, I can't 
remember string delimiter syntax changing since I learned it in 1.3.

> Not having escapes within the expression makes it harder for everyone
> except the Python developer, in my opinion, and the rest of us ought to
> go out of our way for them.

I am not sure that this says what you mean.

-- 
Terry Jan Reedy



More information about the Python-ideas mailing list