python / cpython

The Python programming language
https://www.python.org
Other
63.49k stars 30.41k forks source link

Expression before `=` in an f-string is interpreted like a normal string with escape sequences #124363

Open dscorbett opened 1 month ago

dscorbett commented 1 month ago

Bug report

Bug description:

When an f-string contains an = specifier, the characters before the equals sign are interpreted as if they were within a normal string. In particular, a backslash is always interpreted as starting an escape sequence, even when it doesn’t, which causes unexpected output.

>>> print(f'{br'\N{OX}'=}')
br'🐂'=b'\\N{OX}'
>>> print(f'{b'\N{OX}'=}')
<unknown>:1: SyntaxWarning: invalid escape sequence '\N'
b'🐂'=b'\\N{OX}'
>>> print(f'{r'\xff'=}')
r'ÿ'='\\xff'
>>> print(f'{r'\n'=}')
r'
'='\\n'
>>> print(f'{'\''=}')
'''="'"

Those results are misleading because the expressions printed before the equals signs are either syntax errors or do not match the values printed after the equals signs. I expected these results:

>>> print(f'{br'\N{OX}'=}')
br'\N{OX}'=b'\\N{OX}'
>>> print(f'{b'\N{OX}'=}')
<unknown>:1: SyntaxWarning: invalid escape sequence '\N'
b'\N{OX}'=b'\\N{OX}'
>>> print(f'{r'\xff'=}')
r'\xff'='\\xff'
>>> print(f'{r'\n'=}')
r'\n'='\\n'
>>> print(f'{'\''=}')
'\''="'"

Even when the result is not so misleading, it would still be more helpful for debugging if the output kept the expression unmodified, instead of interpreting the escape sequences. For example, this:

>>> print(f'{'\xc5'=}')
'Å'='Å'

would be better as this:

>>> print(f'{'\xc5'=}')
'\xc5'='Å'

CPython versions tested on:

3.12, 3.13

Operating systems tested on:

macOS

sobolevn commented 1 month ago

cc @pablogsal @lysnikolaou