Skip to content

Commit

Permalink
fix: respect braces better in f-string parsing (#4422)
Browse files Browse the repository at this point in the history
  • Loading branch information
tusharsadhwani authored Aug 2, 2024
1 parent 4b4ae43 commit b1c4dd9
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@

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

- Fix bugs with Black's tokenizer not handling `\{` inside f-strings very well (#4422)

- Fix incorrect line numbers in the tokenizer for certain tokens within f-strings
(#4423)

Expand Down
12 changes: 6 additions & 6 deletions src/blib2to3/pgen2/tokenize.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,12 @@ def _combinations(*l: str) -> Set[str]:
)

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

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

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

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

# First (or only) line of ' or " string.
ContStr = group(
Expand Down
10 changes: 10 additions & 0 deletions tests/data/cases/pep_701.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@
f"{'\''}"
f"{f'\''}"

f'{1}\{{'
f'{2} foo \{{[\}}'
f'\{3}'
rf"\{"a"}"

# output

x = f"foo"
Expand Down Expand Up @@ -264,3 +269,8 @@

f"{'\''}"
f"{f'\''}"

f"{1}\{{"
f"{2} foo \{{[\}}"
f"\{3}"
rf"\{"a"}"

0 comments on commit b1c4dd9

Please sign in to comment.