Skip to content

Commit e19bb21

Browse files
committed
Fix the escaping of '{' and '}' in fstrings.
1 parent 1714444 commit e19bb21

File tree

8 files changed

+80
-16
lines changed

8 files changed

+80
-16
lines changed

grammars/MagicPython.cson

+15-5
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,11 @@ repository:
862862
}
863863
{
864864
name: "constant.character.escape.python"
865-
match: "(\\\\[{}])"
865+
match: "({{|}})"
866+
}
867+
{
868+
name: "invalid.illegal.brace.python"
869+
match: "(}(?!}))"
866870
}
867871
]
868872
"escape-sequence-unicode":
@@ -3381,7 +3385,7 @@ repository:
33813385
name: "string.quoted.single.python"
33823386
match: '''
33833387
(?x)
3384-
(.*?)
3388+
(.+?)
33853389
(
33863390
(?# .* and .*? in multi-line match need special handling of
33873391
newlines otherwise SublimeText and Atom will match slightly
@@ -3391,8 +3395,11 @@ repository:
33913395
lookahead because of special $ matching rule.)
33923396
($\\n?)
33933397
|
3394-
(?=[\\\\\\{]|(['"])|((?<!\\\\)\\n))
3398+
(?=[\\\\\\}\\{]|(['"])|((?<!\\\\)\\n))
33953399
)
3400+
(?# due to how multiline regexps are matched we need a special case
3401+
for matching a newline character)
3402+
| \\n
33963403
33973404
'''
33983405
}
@@ -3450,7 +3457,7 @@ repository:
34503457
name: "string.quoted.multi.python"
34513458
match: '''
34523459
(?x)
3453-
(.*?)
3460+
(.+?)
34543461
(
34553462
(?# .* and .*? in multi-line match need special handling of
34563463
newlines otherwise SublimeText and Atom will match slightly
@@ -3460,8 +3467,11 @@ repository:
34603467
lookahead because of special $ matching rule.)
34613468
($\\n?)
34623469
|
3463-
(?=[\\\\\\{]|\'''|""")
3470+
(?=[\\\\\\}\\{]|\'''|""")
34643471
)
3472+
(?# due to how multiline regexps are matched we need a special case
3473+
for matching a newline character)
3474+
| \\n
34653475
34663476
'''
34673477
}

grammars/MagicPython.tmLanguage

+17-5
Original file line numberDiff line numberDiff line change
@@ -1394,7 +1394,13 @@
13941394
<key>name</key>
13951395
<string>constant.character.escape.python</string>
13961396
<key>match</key>
1397-
<string>(\\[{}])</string>
1397+
<string>({{|}})</string>
1398+
</dict>
1399+
<dict>
1400+
<key>name</key>
1401+
<string>invalid.illegal.brace.python</string>
1402+
<key>match</key>
1403+
<string>(}(?!}))</string>
13981404
</dict>
13991405
</array>
14001406
</dict>
@@ -5756,7 +5762,7 @@ indirectly through syntactic constructs
57565762
<string>string.quoted.single.python</string>
57575763
<key>match</key>
57585764
<string>(?x)
5759-
(.*?)
5765+
(.+?)
57605766
(
57615767
(?# .* and .*? in multi-line match need special handling of
57625768
newlines otherwise SublimeText and Atom will match slightly
@@ -5766,8 +5772,11 @@ indirectly through syntactic constructs
57665772
lookahead because of special $ matching rule.)
57675773
($\n?)
57685774
|
5769-
(?=[\\\{]|(['"])|((?&lt;!\\)\n))
5775+
(?=[\\\}\{]|(['"])|((?&lt;!\\)\n))
57705776
)
5777+
(?# due to how multiline regexps are matched we need a special case
5778+
for matching a newline character)
5779+
| \n
57715780
</string>
57725781
</dict>
57735782
</array>
@@ -5870,7 +5879,7 @@ indirectly through syntactic constructs
58705879
<string>string.quoted.multi.python</string>
58715880
<key>match</key>
58725881
<string>(?x)
5873-
(.*?)
5882+
(.+?)
58745883
(
58755884
(?# .* and .*? in multi-line match need special handling of
58765885
newlines otherwise SublimeText and Atom will match slightly
@@ -5880,8 +5889,11 @@ indirectly through syntactic constructs
58805889
lookahead because of special $ matching rule.)
58815890
($\n?)
58825891
|
5883-
(?=[\\\{]|'''|""")
5892+
(?=[\\\}\{]|'''|""")
58845893
)
5894+
(?# due to how multiline regexps are matched we need a special case
5895+
for matching a newline character)
5896+
| \n
58855897
</string>
58865898
</dict>
58875899
</array>

grammars/src/MagicPython.syntax.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,9 @@ repository:
608608
- include: '#escape-sequence'
609609
- include: '#string-line-continuation'
610610
- name: constant.character.escape.python
611-
match: (\\[{}])
611+
match: ({{|}})
612+
- name: invalid.illegal.brace.python
613+
match: (}(?!}))
612614

613615
escape-sequence-unicode:
614616
patterns:

grammars/src/pyfstring.inc.syntax.yaml

+5-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ repository:
1818
- name: string.quoted.${line}.python
1919
match: |
2020
(?x)
21-
(.*?)
21+
(.+?)
2222
(
2323
(?# .* and .*? in multi-line match need special handling of
2424
newlines otherwise SublimeText and Atom will match slightly
@@ -28,8 +28,11 @@ repository:
2828
lookahead because of special $ matching rule.)
2929
($\n?)
3030
|
31-
(?=[\\\{]|${marker}${guard})
31+
(?=[\\\}\{]|${marker}${guard})
3232
)
33+
(?# due to how multiline regexps are matched we need a special case
34+
for matching a newline character)
35+
| \n
3336
3437
fstring-${line}-brace:
3538
comment: value interpolation using { ... }

misc/scopes

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ invalid.deprecated.backtick.python
3131
invalid.deprecated.prefix.python
3232
invalid.deprecated.semicolon.python
3333
invalid.illegal.annotation.python
34+
invalid.illegal.brace.python
3435
invalid.illegal.dec.python
3536
invalid.illegal.decorator.python
3637
invalid.illegal.line.continuation.python

test/fstrings/simple2.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
a = f"normal \{ normal \} normal {10!r} normal {fo.__add__!s}"
1+
a = f"normal {{ normal }} normal } {10!r} normal {fo.__add__!s}"
22

33

44

@@ -9,10 +9,12 @@
99
f : source.python, storage.type.string.python, string.quoted.single.python
1010
" : punctuation.definition.string.begin.python, source.python, string.quoted.single.python
1111
normal : source.python, string.quoted.single.python
12-
\{ : constant.character.escape.python, source.python
12+
{{ : constant.character.escape.python, source.python
1313
normal : source.python, string.quoted.single.python
14-
\} : constant.character.escape.python, source.python
14+
}} : constant.character.escape.python, source.python
1515
normal : source.python, string.quoted.single.python
16+
} : invalid.illegal.brace.python, source.python
17+
: source.python, string.quoted.single.python
1618
{ : constant.character.format.placeholder.other.python, source.python
1719
10 : constant.numeric.dec.python, source.python
1820
!r : source.python, storage.type.format.python

test/fstrings/simple7.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
f'abc \ efg'
2+
3+
4+
5+
6+
f : source.python, storage.type.string.python, string.quoted.single.python
7+
' : punctuation.definition.string.begin.python, source.python, string.quoted.single.python
8+
abc : source.python, string.quoted.single.python
9+
\ efg : source.python, string.quoted.single.python
10+
' : punctuation.definition.string.end.python, source.python, string.quoted.single.python

test/fstrings/simple8.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
f'abc \} }} }}} }}}} }}}}} efg'
2+
3+
4+
5+
6+
f : source.python, storage.type.string.python, string.quoted.single.python
7+
' : punctuation.definition.string.begin.python, source.python, string.quoted.single.python
8+
abc : source.python, string.quoted.single.python
9+
\ : source.python, string.quoted.single.python
10+
} : invalid.illegal.brace.python, source.python
11+
: source.python, string.quoted.single.python
12+
}} : constant.character.escape.python, source.python
13+
: source.python, string.quoted.single.python
14+
}} : constant.character.escape.python, source.python
15+
} : invalid.illegal.brace.python, source.python
16+
: source.python, string.quoted.single.python
17+
}} : constant.character.escape.python, source.python
18+
}} : constant.character.escape.python, source.python
19+
: source.python, string.quoted.single.python
20+
}} : constant.character.escape.python, source.python
21+
}} : constant.character.escape.python, source.python
22+
} : invalid.illegal.brace.python, source.python
23+
efg : source.python, string.quoted.single.python
24+
' : punctuation.definition.string.end.python, source.python, string.quoted.single.python

0 commit comments

Comments
 (0)