@@ -282,18 +282,15 @@ repository:
282282 match : " \\ b(?<!\\ .)(class)\\ b"
283283 }
284284 ]
285- " expression-base " :
286- comment : " All valid Python expressions"
285+ " expression-bare " :
286+ comment : " valid Python expressions w/o comments and line continuation "
287287 patterns : [
288288 {
289289 include : " #backticks"
290290 }
291291 {
292292 include : " #illegal-anno"
293293 }
294- {
295- include : " #comments"
296- }
297294 {
298295 include : " #literal"
299296 }
@@ -348,11 +345,24 @@ repository:
348345 {
349346 include : " #special-variables"
350347 }
348+ {
349+ include : " #ellipsis"
350+ }
351351 {
352352 include : " #line-continuation"
353353 }
354+ ]
355+ " expression-base" :
356+ comment : " valid Python expressions with comments and line continuation"
357+ patterns : [
358+ {
359+ include : " #comments"
360+ }
354361 {
355- include : " #ellipsis"
362+ include : " #expression-bare"
363+ }
364+ {
365+ include : " #line-continuation"
356366 }
357367 ]
358368 expression :
@@ -869,35 +879,36 @@ repository:
869879 match : " (}(?!}))"
870880 }
871881 ]
872- " fstring-terminator" :
882+ " fstring-illegal-single-brace" :
883+ comment : " it is illegal to have a multiline brace inside a single-line string"
884+ begin : " (\\ {)(?=[^\\ n}]*$\\ n?)"
885+ end : " (\\ })|(?=\\ n)"
886+ beginCaptures :
887+ " 1" :
888+ name : " constant.character.format.placeholder.other.python"
889+ endCaptures :
890+ " 2" :
891+ name : " constant.character.format.placeholder.other.python"
873892 patterns : [
874893 {
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"
894+ include : " #fstring-terminator-single"
887895 }
888896 {
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"
897+ include : " #f-expression"
898+ }
899+ ]
900+ " f-expression" :
901+ comment : " All valid Python expressions, except comments and line cont"
902+ patterns : [
903+ {
904+ include : " #expression-bare"
905+ }
906+ {
907+ include : " #member-access"
908+ }
909+ {
910+ comment : " Tokenize identifiers to help linters"
911+ match : " (?x) \\ b ([[:alpha:]_]\\ w*) \\ b"
901912 }
902913 ]
903914 " escape-sequence-unicode" :
@@ -3409,6 +3420,9 @@ repository:
34093420 {
34103421 include : " #fstring-guts"
34113422 }
3423+ {
3424+ include : " #fstring-illegal-single-brace"
3425+ }
34123426 {
34133427 include : " #fstring-single-brace"
34143428 }
@@ -3440,7 +3454,7 @@ repository:
34403454 begin : " (\\ {)"
34413455 end : '''
34423456 (?x)
3443- (\\ })
3457+ (\\ })|(?= \\ n)
34443458
34453459 '''
34463460 beginCaptures :
@@ -3451,10 +3465,82 @@ repository:
34513465 name : " constant.character.format.placeholder.other.python"
34523466 patterns : [
34533467 {
3454- include : " #fstring-terminator"
3468+ include : " #fstring-terminator-single "
34553469 }
34563470 {
3457- include : " #expression"
3471+ include : " #f-expression"
3472+ }
3473+ ]
3474+ " fstring-terminator-single" :
3475+ patterns : [
3476+ {
3477+ name : " storage.type.format.python"
3478+ match : " (![rsa])(?=})"
3479+ }
3480+ {
3481+ match : '''
3482+ (?x)
3483+ (![rsa])?
3484+ ( : \\ w? [<>=^]? [-+ ]? \\ #?
3485+ \\ d* ,? (\\ .\\ d+)? [bcdeEfFgGnosxX%]? )(?=})
3486+
3487+ '''
3488+ captures :
3489+ " 1" :
3490+ name : " storage.type.format.python"
3491+ " 2" :
3492+ name : " support.other.format.python"
3493+ }
3494+ {
3495+ include : " #fstring-terminator-single-tail"
3496+ }
3497+ ]
3498+ " fstring-terminator-single-tail" :
3499+ begin : " (![rsa])?(:)(?=.*?{)"
3500+ end : " (?=})|(?=\\ n)"
3501+ beginCaptures :
3502+ " 1" :
3503+ name : " storage.type.format.python"
3504+ " 2" :
3505+ name : " support.other.format.python"
3506+ patterns : [
3507+ {
3508+ include : " #fstring-illegal-single-brace"
3509+ }
3510+ {
3511+ include : " #fstring-single-brace"
3512+ }
3513+ {
3514+ name : " support.other.format.python"
3515+ match : " ([bcdeEfFgGnosxX%])(?=})"
3516+ }
3517+ {
3518+ name : " support.other.format.python"
3519+ match : " (\\ .\\ d+)"
3520+ }
3521+ {
3522+ name : " support.other.format.python"
3523+ match : " (,)"
3524+ }
3525+ {
3526+ name : " support.other.format.python"
3527+ match : " (\\ d+)"
3528+ }
3529+ {
3530+ name : " support.other.format.python"
3531+ match : " (\\ #)"
3532+ }
3533+ {
3534+ name : " support.other.format.python"
3535+ match : " ([-+ ])"
3536+ }
3537+ {
3538+ name : " support.other.format.python"
3539+ match : " ([<>=^])"
3540+ }
3541+ {
3542+ name : " support.other.format.python"
3543+ match : " (\\ w)"
34583544 }
34593545 ]
34603546 " fstring-quoted-multi-line" :
@@ -3474,6 +3560,9 @@ repository:
34743560 {
34753561 include : " #fstring-guts"
34763562 }
3563+ {
3564+ include : " #fstring-illegal-multi-brace"
3565+ }
34773566 {
34783567 include : " #fstring-multi-brace"
34793568 }
@@ -3516,9 +3605,81 @@ repository:
35163605 name : " constant.character.format.placeholder.other.python"
35173606 patterns : [
35183607 {
3519- include : " #fstring-terminator"
3608+ include : " #fstring-terminator-multi "
35203609 }
35213610 {
3522- include : " #expression"
3611+ include : " #f-expression"
3612+ }
3613+ ]
3614+ " fstring-terminator-multi" :
3615+ patterns : [
3616+ {
3617+ name : " storage.type.format.python"
3618+ match : " (![rsa])(?=})"
3619+ }
3620+ {
3621+ match : '''
3622+ (?x)
3623+ (![rsa])?
3624+ ( : \\ w? [<>=^]? [-+ ]? \\ #?
3625+ \\ d* ,? (\\ .\\ d+)? [bcdeEfFgGnosxX%]? )(?=})
3626+
3627+ '''
3628+ captures :
3629+ " 1" :
3630+ name : " storage.type.format.python"
3631+ " 2" :
3632+ name : " support.other.format.python"
3633+ }
3634+ {
3635+ include : " #fstring-terminator-multi-tail"
3636+ }
3637+ ]
3638+ " fstring-terminator-multi-tail" :
3639+ begin : " (![rsa])?(:)(?=.*?{)"
3640+ end : " (?=})"
3641+ beginCaptures :
3642+ " 1" :
3643+ name : " storage.type.format.python"
3644+ " 2" :
3645+ name : " support.other.format.python"
3646+ patterns : [
3647+ {
3648+ include : " #fstring-illegal-multi-brace"
3649+ }
3650+ {
3651+ include : " #fstring-multi-brace"
3652+ }
3653+ {
3654+ name : " support.other.format.python"
3655+ match : " ([bcdeEfFgGnosxX%])(?=})"
3656+ }
3657+ {
3658+ name : " support.other.format.python"
3659+ match : " (\\ .\\ d+)"
3660+ }
3661+ {
3662+ name : " support.other.format.python"
3663+ match : " (,)"
3664+ }
3665+ {
3666+ name : " support.other.format.python"
3667+ match : " (\\ d+)"
3668+ }
3669+ {
3670+ name : " support.other.format.python"
3671+ match : " (\\ #)"
3672+ }
3673+ {
3674+ name : " support.other.format.python"
3675+ match : " ([-+ ])"
3676+ }
3677+ {
3678+ name : " support.other.format.python"
3679+ match : " ([<>=^])"
3680+ }
3681+ {
3682+ name : " support.other.format.python"
3683+ match : " (\\ w)"
35233684 }
35243685 ]
0 commit comments