classification
Title: Parsing error on f-string-expressions containing strings with backslash
Type: behavior Stage: resolved
Components: Versions: Python 3.7
process
Status: closed Resolution: postponed
Dependencies: Superseder:
Assigned To: eric.smith Nosy List: Anselm Kiefner, eric.smith
Priority: normal Keywords:

Created on 2017-06-28 18:58 by Anselm Kiefner, last changed 2019-05-06 12:29 by eric.smith. This issue is now closed.

Messages (7)
msg297206 - (view) Author: Anselm Kiefner (Anselm Kiefner) Date: 2017-06-28 18:58
Considering that

x = 3
f"{'hello' if x == 3 else 'goodbye'} world"

is a simple, elegant and powerful piece of code that works just as expected by itself, I often find myself stumbling and wondering why
 
f"text {'\n' if x == 3 else ''} text"

fails horribly just because of the \ within the extra quoted string that must be worked around with ugly code like

nl = "\n"
f"text {nl if x==3 else ''} text"

which really doesn't feel like python at all.

I am aware that the specification for f-strings says "no \ in expressions", but please consider that in this case, the \ is not really part of the expression but rather part of a string that isn't evaluated as part of the expression, which might just as well be referenced to by a variable.
msg297240 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2017-06-28 22:43
The reason that this was done was to give us flexibility in deciding how the backslashes should be interpreted in the future. I announced it on python-dev here: https://mail.python.org/pipermail/python-dev/2016-August/145979.html. That message contains a link to the python-ideas discussion that precipitated the change.

PEP 536 is one proposal to change how this is handled. I don't entirely agree with it, since I think allowing:
f'Magic wand: { bag['wand'] }'
would be confusing and make life more difficult for simple (regex based) parsers to skip over f-strings.

Notice that in Jupiter (https://github.com/jupyter/notebook/issues/2037#issuecomment-272466046) and in CodeMirror (https://github.com/codemirror/CodeMirror/commit/c45674b11e990fe37abc662b0c507d3bb1f635e7#diff-04f7f1f1bbbab888742c7e849187a79c) they were able to make simple changes to their parsers and "support" f-strings (for some value of "support": mostly not break in the presence of f-strings).

However, I'm not completely opposed to revisiting the issue. Your use case is certainly a compelling one.
msg301541 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2017-09-06 23:17
I'm thinking that instead of supporting backslashes in general inside expressions, I'll just special case strings.

So:
f"{'\n' if foo else ''}"
would be okay, but not:
f"{a\
}"

I think that would address the reason why \ was disallowed, but I'm going to have to go back and review the discussions to make sure.
msg301579 - (view) Author: Anselm Kiefner (Anselm Kiefner) Date: 2017-09-07 09:43
Hey Eric, just a heads up.

In the latest jupyter notebook, this is valid code:

f"{eval('bool(0)\
and True\
')}"

which returns
'False'

I don't know how far you want to go, but if someone REALLY wants to use backspace in f-strings just for the sake of it - however ugly it looks like - they already can.
msg301603 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2017-09-07 18:14
That code is an error in Python 3.6:

>>> f"{eval('bool(0)\
... and True\
... ')}"
  File "<stdin>", line 3
SyntaxError: f-string expression part cannot include a backslash
>>> 

I'm not sure it's a good idea that jupyter accepts code that's not valid in Python itself.
msg301604 - (view) Author: Anselm Kiefner (Anselm Kiefner) Date: 2017-09-07 18:26
Heh. I had a hunch it could be jupyter specific, but didn't test it. They had problems with f-strings before, it seems they over-fixed those ..
Maybe you want to check their implementation and see if it's any good for a general solution?
Otherwise I'd volunteer to submit a bug report for their code ;)
msg341493 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2019-05-06 12:29
I'm going to close this. Either this problem is going to be addressed independently of this issue, or it's never going to be fixed. Either way, we don't need this issue to be open in order to come to a resolution.
History
Date User Action Args
2019-05-06 12:29:10eric.smithsetstatus: open -> closed
resolution: postponed
messages: + msg341493

stage: resolved
2017-09-07 18:26:09Anselm Kiefnersetmessages: + msg301604
2017-09-07 18:14:36eric.smithsetmessages: + msg301603
2017-09-07 09:43:58Anselm Kiefnersetmessages: + msg301579
2017-09-06 23:17:36eric.smithsetmessages: + msg301541
2017-06-28 22:43:53eric.smithsetassignee: eric.smith

messages: + msg297240
nosy: + eric.smith
2017-06-28 18:58:13Anselm Kiefnercreate