classification
Title: fstring's '{' from escape sequences does not start an expression
Type: behavior Stage: resolved
Components: Documentation Versions: Python 3.6
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: jaraco Nosy List: afg984, docs@python, eric.smith, jaraco, python-dev
Priority: normal Keywords:

Created on 2016-11-02 14:58 by afg984, last changed 2016-11-06 17:04 by eric.smith. This issue is now closed.

Messages (6)
msg279927 - (view) Author: afg984 (afg984) Date: 2016-11-02 14:58
PEP 498 says: (https://www.python.org/dev/peps/pep-0498/#escape-sequences)

Scanning an f-string for expressions happens after escape sequences are decoded. Because hex(ord('{')) == 0x7b , the f-string f'\u007b4*10}' is decoded to f'{4*10}' , which evaluates as the integer 40:

    >>> f'\u007b4*10}'
    '40'

However, in python3.6.0b3, the '{' from '\u007b4' does not start an expression, making the remaining '}' invalid:

    >>> f'\u007b4*10}'
      File "<stdin>", line 1
    SyntaxError: f-string: single '}' is not allowed

There's even a test case for it: (Lib/test/test_fstring.py:383)

    def test_no_escapes_for_braces(self):
        # \x7b is '{'.  Make sure it doesn't start an expression.
        self.assertEqual(f'\x7b2}}', '{2}')
        self.assertEqual(f'\x7b2', '{2')
        self.assertEqual(f'\u007b2', '{2')
        self.assertEqual(f'\N{LEFT CURLY BRACKET}2\N{RIGHT CURLY BRACKET}', '{2}')
msg279929 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2016-11-02 15:21
I'm currently working on an update to PEP-498 to address this. I hope to have it completed after a sprint this weekend.
msg280142 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2016-11-06 15:45
I've got a patch ready for this and will be applying it shortly after we update the spec.
msg280144 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2016-11-06 16:10
The reason that those test_no_escapes_for_braces assertions pass is because they're only dealing with opening curly braces and in an f-string, they're treated as literal opening braces.

In the example you've given, the error occurs when the f-string handler encounters the closing curly brace without an opening one. It's the same as if you had written:

    >>> f'{{4*10}'
    SyntaxError: f-string: single '}' is not allowed

I will add a test to capture this specific case (backslash-escaped unicode opening bracken).
msg280145 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2016-11-06 16:15
New changeset 1d8b8a67b657 by Jason R. Coombs in branch '3.6':
Additionally show that a backslash-escaped opening brace is treated as a literal and thus triggers the single closing brace error, clarifying #28590.
https://hg.python.org/cpython/rev/1d8b8a67b657
msg280151 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2016-11-06 17:04
Thanks, Jason. I updated the PEP, so now I think the docs and PEP match the implementation.
History
Date User Action Args
2016-11-06 17:04:26eric.smithsetstatus: open -> closed
resolution: fixed
messages: + msg280151

stage: resolved
2016-11-06 16:15:02python-devsetnosy: + python-dev
messages: + msg280145
2016-11-06 16:10:37jaracosetmessages: + msg280144
2016-11-06 15:45:57jaracosetassignee: docs@python -> jaraco

messages: + msg280142
nosy: + jaraco
2016-11-03 13:47:14eric.smithlinkissue28597 superseder
2016-11-02 15:21:22eric.smithsetmessages: + msg279929
2016-11-02 15:14:08serhiy.storchakasetassignee: docs@python

components: + Documentation, - Interpreter Core
nosy: + docs@python
2016-11-02 15:10:14SilentGhostsetnosy: + eric.smith
2016-11-02 14:58:03afg984create