Skip to content

Commit 8beee2f

Browse files
committed
Partial fix to handling of '#' in fstring format spec.
1 parent e19bb21 commit 8beee2f

File tree

11 files changed

+213
-50
lines changed

11 files changed

+213
-50
lines changed

grammars/MagicPython.cson

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,37 @@ repository:
869869
match: "(}(?!}))"
870870
}
871871
]
872+
"fstring-terminator":
873+
patterns: [
874+
{
875+
match: '''
876+
(?x)
877+
(![rsa])
878+
( : \\w? [<>=^]? [-+ ]? \\#?
879+
\\d* ,? (\\.\\d+)? [bcdeEfFgGnosxX%]? )?
880+
881+
'''
882+
captures:
883+
"1":
884+
name: "storage.type.format.python"
885+
"2":
886+
name: "support.other.format.python"
887+
}
888+
{
889+
match: '''
890+
(?x)
891+
(![rsa])?
892+
( : \\w? [<>=^]? [-+ ]? \\#?
893+
\\d* ,? (\\.\\d+)? [bcdeEfFgGnosxX%]? )
894+
895+
'''
896+
captures:
897+
"1":
898+
name: "storage.type.format.python"
899+
"2":
900+
name: "support.other.format.python"
901+
}
902+
]
872903
"escape-sequence-unicode":
873904
patterns: [
874905
{
@@ -3409,9 +3440,6 @@ repository:
34093440
begin: "(\\{)"
34103441
end: '''
34113442
(?x)
3412-
(![rsa])?
3413-
( : \\w? [<>=^]? [-+ ]? \\#?
3414-
\\d* ,? (\\.\\d+)? [bcdeEfFgGnosxX%]? )?
34153443
(\\})
34163444
34173445
'''
@@ -3420,10 +3448,6 @@ repository:
34203448
name: "constant.character.format.placeholder.other.python"
34213449
endCaptures:
34223450
"1":
3423-
name: "storage.type.format.python"
3424-
"2":
3425-
name: "support.other.format.python"
3426-
"4":
34273451
name: "constant.character.format.placeholder.other.python"
34283452
patterns: [
34293453
{
@@ -3481,9 +3505,6 @@ repository:
34813505
begin: "(\\{)"
34823506
end: '''
34833507
(?x)
3484-
(![rsa])?
3485-
( : \\w? [<>=^]? [-+ ]? \\#?
3486-
\\d* ,? (\\.\\d+)? [bcdeEfFgGnosxX%]? )?
34873508
(\\})
34883509
34893510
'''
@@ -3492,10 +3513,6 @@ repository:
34923513
name: "constant.character.format.placeholder.other.python"
34933514
endCaptures:
34943515
"1":
3495-
name: "storage.type.format.python"
3496-
"2":
3497-
name: "support.other.format.python"
3498-
"4":
34993516
name: "constant.character.format.placeholder.other.python"
35003517
patterns: [
35013518
{

grammars/MagicPython.tmLanguage

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,6 +1404,54 @@
14041404
</dict>
14051405
</array>
14061406
</dict>
1407+
<key>fstring-terminator</key>
1408+
<dict>
1409+
<key>patterns</key>
1410+
<array>
1411+
<dict>
1412+
<key>match</key>
1413+
<string>(?x)
1414+
(![rsa])
1415+
( : \w? [&lt;&gt;=^]? [-+ ]? \#?
1416+
\d* ,? (\.\d+)? [bcdeEfFgGnosxX%]? )?
1417+
</string>
1418+
<key>captures</key>
1419+
<dict>
1420+
<key>1</key>
1421+
<dict>
1422+
<key>name</key>
1423+
<string>storage.type.format.python</string>
1424+
</dict>
1425+
<key>2</key>
1426+
<dict>
1427+
<key>name</key>
1428+
<string>support.other.format.python</string>
1429+
</dict>
1430+
</dict>
1431+
</dict>
1432+
<dict>
1433+
<key>match</key>
1434+
<string>(?x)
1435+
(![rsa])?
1436+
( : \w? [&lt;&gt;=^]? [-+ ]? \#?
1437+
\d* ,? (\.\d+)? [bcdeEfFgGnosxX%]? )
1438+
</string>
1439+
<key>captures</key>
1440+
<dict>
1441+
<key>1</key>
1442+
<dict>
1443+
<key>name</key>
1444+
<string>storage.type.format.python</string>
1445+
</dict>
1446+
<key>2</key>
1447+
<dict>
1448+
<key>name</key>
1449+
<string>support.other.format.python</string>
1450+
</dict>
1451+
</dict>
1452+
</dict>
1453+
</array>
1454+
</dict>
14071455
<key>escape-sequence-unicode</key>
14081456
<dict>
14091457
<key>patterns</key>
@@ -5789,9 +5837,6 @@ indirectly through syntactic constructs
57895837
<string>(\{)</string>
57905838
<key>end</key>
57915839
<string>(?x)
5792-
(![rsa])?
5793-
( : \w? [&lt;&gt;=^]? [-+ ]? \#?
5794-
\d* ,? (\.\d+)? [bcdeEfFgGnosxX%]? )?
57955840
(\})
57965841
</string>
57975842
<key>beginCaptures</key>
@@ -5805,16 +5850,6 @@ indirectly through syntactic constructs
58055850
<key>endCaptures</key>
58065851
<dict>
58075852
<key>1</key>
5808-
<dict>
5809-
<key>name</key>
5810-
<string>storage.type.format.python</string>
5811-
</dict>
5812-
<key>2</key>
5813-
<dict>
5814-
<key>name</key>
5815-
<string>support.other.format.python</string>
5816-
</dict>
5817-
<key>4</key>
58185853
<dict>
58195854
<key>name</key>
58205855
<string>constant.character.format.placeholder.other.python</string>
@@ -5906,9 +5941,6 @@ indirectly through syntactic constructs
59065941
<string>(\{)</string>
59075942
<key>end</key>
59085943
<string>(?x)
5909-
(![rsa])?
5910-
( : \w? [&lt;&gt;=^]? [-+ ]? \#?
5911-
\d* ,? (\.\d+)? [bcdeEfFgGnosxX%]? )?
59125944
(\})
59135945
</string>
59145946
<key>beginCaptures</key>
@@ -5922,16 +5954,6 @@ indirectly through syntactic constructs
59225954
<key>endCaptures</key>
59235955
<dict>
59245956
<key>1</key>
5925-
<dict>
5926-
<key>name</key>
5927-
<string>storage.type.format.python</string>
5928-
</dict>
5929-
<key>2</key>
5930-
<dict>
5931-
<key>name</key>
5932-
<string>support.other.format.python</string>
5933-
</dict>
5934-
<key>4</key>
59355957
<dict>
59365958
<key>name</key>
59375959
<string>constant.character.format.placeholder.other.python</string>

grammars/src/MagicPython.syntax.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,26 @@ repository:
612612
- name: invalid.illegal.brace.python
613613
match: (}(?!}))
614614

615+
fstring-terminator:
616+
patterns:
617+
- match: |
618+
(?x)
619+
(![rsa])
620+
( : \w? [<>=^]? [-+ ]? \#?
621+
\d* ,? (\.\d+)? [bcdeEfFgGnosxX%]? )?
622+
captures:
623+
'1': {name: storage.type.format.python}
624+
'2': {name: support.other.format.python}
625+
626+
- match: |
627+
(?x)
628+
(![rsa])?
629+
( : \w? [<>=^]? [-+ ]? \#?
630+
\d* ,? (\.\d+)? [bcdeEfFgGnosxX%]? )
631+
captures:
632+
'1': {name: storage.type.format.python}
633+
'2': {name: support.other.format.python}
634+
615635
escape-sequence-unicode:
616636
patterns:
617637
- name: constant.character.escape.python

grammars/src/pyfstring.inc.syntax.yaml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,11 @@ repository:
3939
begin: (\{)
4040
end: |
4141
(?x)
42-
(![rsa])?
43-
( : \w? [<>=^]? [-+ ]? \#?
44-
\d* ,? (\.\d+)? [bcdeEfFgGnosxX%]? )?
4542
(\})
4643
beginCaptures:
4744
'1': {name: constant.character.format.placeholder.other.python}
4845
endCaptures:
49-
'1': {name: storage.type.format.python}
50-
'2': {name: support.other.format.python}
51-
'4': {name: constant.character.format.placeholder.other.python}
46+
'1': {name: constant.character.format.placeholder.other.python}
5247
patterns:
5348
- include: '#fstring-terminator'
5449
- include: '#expression'

test/fstrings/comment1.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
f'prefix{10 # comment, making the string technically illegal
2+
def foo(): pass
3+
4+
5+
6+
7+
f : source.python, storage.type.string.python, string.quoted.single.python
8+
' : punctuation.definition.string.begin.python, source.python, string.quoted.single.python
9+
prefix : source.python, string.quoted.single.python
10+
{ : constant.character.format.placeholder.other.python, source.python
11+
10 : constant.numeric.dec.python, source.python
12+
: source.python
13+
# : comment.line.number-sign.python, punctuation.definition.comment.python, source.python
14+
comment, making the string technically illegal : comment.line.number-sign.python, source.python
15+
def : keyword.control.flow.python, source.python
16+
: source.python
17+
foo : meta.function-call.generic.python, meta.function-call.python, source.python
18+
( : meta.function-call.python, punctuation.definition.arguments.begin.python, source.python
19+
) : meta.function-call.python, punctuation.definition.arguments.end.python, source.python
20+
: : source.python, support.other.format.python
21+
pass : keyword.control.flow.python, source.python

test/fstrings/comment2.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
f'''
2+
prefix{10 # comment, perfectly legal
3+
} suffix'''
4+
5+
6+
7+
8+
f : source.python, storage.type.string.python, string.quoted.multi.python
9+
''' : punctuation.definition.string.begin.python, source.python, string.quoted.multi.python
10+
: source.python, string.quoted.multi.python
11+
prefix : source.python, string.quoted.multi.python
12+
{ : constant.character.format.placeholder.other.python, source.python
13+
10 : constant.numeric.dec.python, source.python
14+
: source.python
15+
# : comment.line.number-sign.python, punctuation.definition.comment.python, source.python
16+
comment, perfectly legal : comment.line.number-sign.python, source.python
17+
: source.python
18+
} : constant.character.format.placeholder.other.python, source.python
19+
suffix : source.python, string.quoted.multi.python
20+
''' : punctuation.definition.string.end.python, source.python, string.quoted.multi.python

test/fstrings/comment3.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
self.assertEqual(f'{10:#{3 != {4:5} and width}x}', ' 0xa')
2+
3+
4+
5+
6+
self : source.python, variable.language.special.self.python
7+
. : source.python
8+
assertEqual : meta.function-call.generic.python, meta.function-call.python, source.python
9+
( : meta.function-call.python, punctuation.definition.arguments.begin.python, source.python
10+
f : meta.function-call.arguments.python, meta.function-call.python, source.python, storage.type.string.python, string.quoted.single.python
11+
' : meta.function-call.arguments.python, meta.function-call.python, punctuation.definition.string.begin.python, source.python, string.quoted.single.python
12+
{ : constant.character.format.placeholder.other.python, meta.function-call.arguments.python, meta.function-call.python, source.python
13+
10 : constant.numeric.dec.python, meta.function-call.arguments.python, meta.function-call.python, source.python
14+
:# : meta.function-call.arguments.python, meta.function-call.python, source.python, support.other.format.python
15+
{ : meta.function-call.arguments.python, meta.function-call.python, punctuation.definition.dict.begin.python, source.python
16+
3 : constant.numeric.dec.python, meta.function-call.arguments.python, meta.function-call.python, source.python
17+
: meta.function-call.arguments.python, meta.function-call.python, source.python
18+
!= : keyword.operator.comparison.python, meta.function-call.arguments.python, meta.function-call.python, source.python
19+
: meta.function-call.arguments.python, meta.function-call.python, source.python
20+
{ : meta.function-call.arguments.python, meta.function-call.python, punctuation.definition.dict.begin.python, source.python
21+
4 : constant.numeric.dec.python, meta.function-call.arguments.python, meta.function-call.python, source.python
22+
: : meta.function-call.arguments.python, meta.function-call.python, source.python
23+
5 : constant.numeric.dec.python, meta.function-call.arguments.python, meta.function-call.python, source.python
24+
} : meta.function-call.arguments.python, meta.function-call.python, punctuation.definition.dict.end.python, source.python
25+
: meta.function-call.arguments.python, meta.function-call.python, source.python
26+
and : keyword.operator.logical.python, meta.function-call.arguments.python, meta.function-call.python, source.python
27+
: meta.function-call.arguments.python, meta.function-call.python, source.python
28+
width : meta.function-call.arguments.python, meta.function-call.python, source.python
29+
} : meta.function-call.arguments.python, meta.function-call.python, punctuation.definition.dict.end.python, source.python
30+
x : meta.function-call.arguments.python, meta.function-call.python, source.python
31+
} : constant.character.format.placeholder.other.python, meta.function-call.arguments.python, meta.function-call.python, source.python
32+
' : meta.function-call.arguments.python, meta.function-call.python, punctuation.definition.string.end.python, source.python, string.quoted.single.python
33+
, : meta.function-call.arguments.python, meta.function-call.python, punctuation.separator.arguments.python, source.python
34+
: meta.function-call.arguments.python, meta.function-call.python, source.python
35+
' : meta.function-call.arguments.python, meta.function-call.python, punctuation.definition.string.begin.python, source.python, string.quoted.single.python
36+
0xa : meta.function-call.arguments.python, meta.function-call.python, source.python, string.quoted.single.python
37+
' : meta.function-call.arguments.python, meta.function-call.python, punctuation.definition.string.end.python, source.python, string.quoted.single.python
38+
) : meta.function-call.python, punctuation.definition.arguments.end.python, source.python

test/fstrings/nested1.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def : keyword.control.flow.python, meta.function-call.arguments.python
5252
aaa : meta.function-call.arguments.python, meta.function-call.generic.python, meta.function-call.python, source.python
5353
( : meta.function-call.arguments.python, meta.function-call.python, punctuation.definition.arguments.begin.python, source.python
5454
) : meta.function-call.arguments.python, meta.function-call.python, punctuation.definition.arguments.end.python, source.python
55-
: : meta.function-call.arguments.python, meta.function-call.python, source.python
55+
: : meta.function-call.arguments.python, meta.function-call.python, source.python, support.other.format.python
5656
pass : keyword.control.flow.python, meta.function-call.arguments.python, meta.function-call.python, source.python
5757
} : constant.character.format.placeholder.other.python, meta.function-call.arguments.python, meta.function-call.python, source.python
5858
111 : meta.function-call.arguments.python, meta.function-call.python, source.python, string.quoted.single.python

test/fstrings/nested2.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
f"result: {value:{60}.{16!s:2}{'qwerty'[2]}}"
2+
3+
4+
5+
f : source.python, storage.type.string.python, string.quoted.single.python
6+
" : punctuation.definition.string.begin.python, source.python, string.quoted.single.python
7+
result: : source.python, string.quoted.single.python
8+
{ : constant.character.format.placeholder.other.python, source.python
9+
value : source.python
10+
: : source.python, support.other.format.python
11+
{ : punctuation.definition.dict.begin.python, source.python
12+
60 : constant.numeric.dec.python, source.python
13+
} : punctuation.definition.dict.end.python, source.python
14+
. : source.python
15+
{ : punctuation.definition.dict.begin.python, source.python
16+
16 : constant.numeric.dec.python, source.python
17+
! : invalid.illegal.operator.python, source.python
18+
s : source.python
19+
: : source.python
20+
2 : constant.numeric.dec.python, source.python
21+
} : punctuation.definition.dict.end.python, source.python
22+
{ : punctuation.definition.dict.begin.python, source.python
23+
' : punctuation.definition.string.begin.python, source.python, string.quoted.single.python
24+
qwerty : source.python, string.quoted.single.python
25+
' : punctuation.definition.string.end.python, source.python, string.quoted.single.python
26+
[ : punctuation.definition.list.begin.python, source.python
27+
2 : constant.numeric.dec.python, source.python
28+
] : punctuation.definition.list.end.python, source.python
29+
} : punctuation.definition.dict.end.python, source.python
30+
} : constant.character.format.placeholder.other.python, source.python
31+
" : punctuation.definition.string.end.python, source.python, string.quoted.single.python

test/fstrings/simple1.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@
4545
[ : punctuation.definition.list.begin.python, source.python
4646
: source.python
4747
] : punctuation.definition.list.end.python, source.python
48-
: : source.python
49-
Xd : source.python
48+
:Xd : source.python, support.other.format.python
5049
> : keyword.operator.comparison.python, source.python
5150
+ : keyword.operator.arithmetic.python, source.python
5251
10d : invalid.illegal.name.python, source.python

0 commit comments

Comments
 (0)