Skip to content

Commit b1c4dd9

Browse files
fix: respect braces better in f-string parsing (#4422)
1 parent 4b4ae43 commit b1c4dd9

File tree

3 files changed

+18
-6
lines changed

3 files changed

+18
-6
lines changed

CHANGES.md

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939

4040
- Fix bug with Black incorrectly parsing empty lines with a backslash (#4343)
4141

42+
- Fix bugs with Black's tokenizer not handling `\{` inside f-strings very well (#4422)
43+
4244
- Fix incorrect line numbers in the tokenizer for certain tokens within f-strings
4345
(#4423)
4446

src/blib2to3/pgen2/tokenize.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,12 @@ def _combinations(*l: str) -> Set[str]:
136136
)
137137

138138
# beginning of a single quoted f-string. must not end with `{{` or `\N{`
139-
SingleLbrace = r"(?:\\N{|\\.|{{|[^'\\{])*(?<!\\N){(?!{)"
140-
DoubleLbrace = r'(?:\\N{|\\.|{{|[^"\\{])*(?<!\\N){(?!{)'
139+
SingleLbrace = r"(?:\\N{|{{|\\'|[^\n'{])*(?<!\\N)({)(?!{)"
140+
DoubleLbrace = r'(?:\\N{|{{|\\"|[^\n"{])*(?<!\\N)({)(?!{)'
141141

142142
# beginning of a triple quoted f-string. must not end with `{{` or `\N{`
143-
Single3Lbrace = r"(?:\\N{|\\[^{]|{{|'(?!'')|[^'{\\])*(?<!\\N){(?!{)"
144-
Double3Lbrace = r'(?:\\N{|\\[^{]|{{|"(?!"")|[^"{\\])*(?<!\\N){(?!{)'
143+
Single3Lbrace = r"(?:\\N{|{{|\\'|'(?!'')|[^'{])*(?<!\\N){(?!{)"
144+
Double3Lbrace = r'(?:\\N{|{{|\\"|"(?!"")|[^"{])*(?<!\\N){(?!{)'
145145

146146
# ! format specifier inside an fstring brace, ensure it's not a `!=` token
147147
Bang = Whitespace + group("!") + r"(?!=)"
@@ -175,8 +175,8 @@ def _combinations(*l: str) -> Set[str]:
175175
_string_middle_double = r'(?:[^\n"\\]|\\.)*'
176176

177177
# FSTRING_MIDDLE and LBRACE, must not end with a `{{` or `\N{`
178-
_fstring_middle_single = r"(?:\\N{|\\[^{]|{{|[^\n'{\\])*(?<!\\N)({)(?!{)"
179-
_fstring_middle_double = r'(?:\\N{|\\[^{]|{{|[^\n"{\\])*(?<!\\N)({)(?!{)'
178+
_fstring_middle_single = SingleLbrace
179+
_fstring_middle_double = DoubleLbrace
180180

181181
# First (or only) line of ' or " string.
182182
ContStr = group(

tests/data/cases/pep_701.py

+10
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@
131131
f"{'\''}"
132132
f"{f'\''}"
133133

134+
f'{1}\{{'
135+
f'{2} foo \{{[\}}'
136+
f'\{3}'
137+
rf"\{"a"}"
138+
134139
# output
135140

136141
x = f"foo"
@@ -264,3 +269,8 @@
264269

265270
f"{'\''}"
266271
f"{f'\''}"
272+
273+
f"{1}\{{"
274+
f"{2} foo \{{[\}}"
275+
f"\{3}"
276+
rf"\{"a"}"

0 commit comments

Comments
 (0)