syntax_test_python_strings.py (28371B)
1 # SYNTAX TEST "Packages/Python/Python.sublime-syntax" 2 3 ############################### 4 # Strings and embedded syntaxes 5 ############################### 6 7 var = "\x00 \xaa \xAF \070 \0 \r \n \t \\ \a \b \' \v \f \u0aF1 \UFe0a182f \N{SPACE}" 8 # ^ meta.string.python 9 # ^^^^ constant.character.escape.hex 10 # ^^^^ constant.character.escape.hex 11 # ^^^^ constant.character.escape.hex 12 # ^^^^ constant.character.escape.octal 13 # ^^ constant.character.escape 14 # ^^ constant.character.escape 15 # ^^ constant.character.escape 16 # ^^ constant.character.escape 17 # ^^ constant.character.escape 18 # ^^ constant.character.escape 19 # ^^ constant.character.escape 20 # ^^ constant.character.escape 21 # ^^ constant.character.escape 22 # ^^ constant.character.escape 23 # ^^^^^^ constant.character.escape.unicode 24 # ^^^^^^^^^^ constant.character.escape.unicode 25 # ^^^^^^^^^ constant.character.escape.unicode 26 27 invalid_escapes = "\. \-" 28 # ^^ invalid.deprecated.character.escape.python 29 # ^^ invalid.deprecated.character.escape.python 30 31 conn.execute("SELECT * FROM foobar") 32 # ^ meta.string.python keyword.other.DML.sql 33 34 conn.execute('SELECT * FROM foobar') 35 # ^ keyword.other.DML.sql 36 37 conn.execute(U"SELECT * FROM foobar") 38 # ^ keyword.other.DML.sql 39 40 conn.execute(U'SELECT * FROM foobar') 41 # ^ keyword.other.DML.sql 42 43 # In this example, the Python string is not raw, so \t is a python escape 44 conn.execute(u"SELECT * FROM foobar WHERE foo = '\t'") 45 # ^ keyword.other.DML.sql 46 # ^ constant.character.escape.python 47 48 conn.execute(u'SELECT * FROM foobar') 49 # ^ keyword.other.DML.sql 50 51 # In this example, the Python string is raw, so the \b should be a SQL escape 52 conn.execute(r"SELECT * FROM foobar WHERE baz = '\b") 53 # ^ meta.string.python keyword.other.DML.sql 54 # ^ constant.character.escape.sql 55 56 # This tests to ensure the Python placeholder will be highlighted even in a raw SQL string 57 conn.execute(r'SELECT * FROM foobar WHERE %s') 58 # ^ keyword.other.DML.sql 59 # ^ constant.other.placeholder.python 60 61 conn.execute(r"SELECT * FROM foobar") 62 # ^ keyword.other.DML.sql 63 64 conn.execute(r'SELECT * FROM foobar') 65 # ^ keyword.other.DML.sql 66 67 conn.execute(r"""SELECT * FROM foobar WHERE %s and foo = '\t'""") 68 # ^ keyword.other.DML.sql 69 # ^ constant.other.placeholder.python 70 # ^ constant.character.escape.sql 71 72 # Capital R prevents all syntax embedding 73 conn.execute(R'SELECT * FROM foobar') 74 # ^ meta.string.python - keyword.other.DML.sql 75 76 conn.execute(R"SELECT * FROM foobar") 77 # ^ - keyword.other.DML.sql 78 79 conn.execute(R"""SELECT * FROM foobar""") 80 # ^ - keyword.other.DML.sql 81 82 conn.execute(r'''SELECT * FROM foobar''') 83 # ^ keyword.other.DML.sql 84 85 conn.execute(u"""SELECT * FROM foobar WHERE %s and foo = '\t'""") 86 # ^ keyword.other.DML.sql 87 # ^ constant.other.placeholder.python 88 # ^ constant.character.escape.python 89 90 regex = r'\b ([fobar]*){1}(?:a|b)?' 91 # ^ meta.string.python keyword.control.anchor.regexp 92 # ^ keyword.operator.quantifier.regexp 93 94 regex = r'.* # Not a comment (yet)' 95 # ^^^^^^^^^^^^^^^^^^^^^ - comment 96 # ^ punctuation.definition.string.end.python - comment 97 # ^ - invalid 98 99 regex = r".* # Not a comment (yet)" 100 # ^^^^^^^^^^^^^^^^^^^^^ - comment 101 # ^ punctuation.definition.string.end.python - comment 102 # ^ - invalid 103 104 regex = r'''\b ([fobar]*){1}(?:a|b)?''' 105 # ^ keyword.control.anchor.regexp 106 # ^ keyword.operator.quantifier.regexp 107 108 regex = r"""\b ([fobar]*){1}(?:a|b)?""" 109 # ^ keyword.control.anchor.regexp 110 # ^ keyword.operator.quantifier.regexp 111 112 # Capital R prevents all syntax embedding 113 regex = R'\b ([fobar]*){1}(?:a|b)?' 114 # ^ - keyword.control.anchor.regexp 115 # ^ - keyword.operator.quantifier.regexp 116 117 regex = R"\b ([fobar]*){1}(?:a|b)?" 118 # ^ - keyword.control.anchor.regexp 119 # ^ - keyword.operator.quantifier.regexp 120 121 bad_string = 'SELECT * FROM users 122 # ^ invalid.illegal.unclosed-string 123 124 more_bad_string = r" 125 # ^ invalid.illegal.unclosed-string.python 126 127 string = ''' 128 129 # <- string.quoted.single.block 130 ''' 131 132 string = """ 133 134 # <- string.quoted.double.block 135 """ 136 137 string = """ 138 # ^^^ string.quoted.double.block - string string 139 \ 140 # <- punctuation.separator.continuation.line.python 141 """ 142 143 string = r""" 144 # ^^^ meta.string.python string.quoted.double.block 145 \ 146 # <- - punctuation 147 """ 148 149 string = r""" 150 # An indented comment. 151 # ^ - comment 152 # ^ comment.line.number-sign.regexp 153 ### <<This comment>> @includes some &punctutation. 154 # <- comment.line.number-sign.regexp 155 """ 156 157 string = ''' 158 # ^^^ string.quoted.single.block 159 ''' 160 161 string = r''' 162 # ^^^ string.quoted.single.block 163 ''' 164 165 string = r''' 166 # An indented comment. 167 # ^ - comment 168 # ^ comment.line.number-sign.regexp 169 ### <<This comment>> @includes some &punctutation. 170 # <- comment.line.number-sign.regexp 171 ''' 172 173 string = r''' 174 [set] 175 # ^^^^^ constant.other.character-class.set.regexp 176 # ^ punctuation.definition.character-class.begin.regexp 177 # ^ punctuation.definition.character-class.end.regexp 178 (group) 179 # ^^^^^^^ meta.group.regexp 180 # ^ punctuation.definition.group.begin.regexp 181 # ^ punctuation.definition.group.end.regexp 182 (?<!group) 183 # ^^^^^^^^^^ meta.group.assertion.regexp 184 # ^ punctuation.definition.group.begin.regexp 185 # ^^^ constant.other.assertion.regexp 186 # ^ punctuation.definition.group.end.regexp 187 ''' 188 189 query = \ 190 """ 191 SELECT 192 ( 193 SELECT CASE field 194 WHEN 1 195 THEN -- comment's say that 196 # ^ source.sql comment.line.double-dash 197 EXISTS( 198 select 1) 199 ELSE NULL 200 ) as result 201 """ 202 203 query = \ 204 r""" 205 206 SELECT 207 ( 208 SELECT CASE field 209 WHEN 1 210 THEN -- comment's say that 211 # ^ source.sql comment.line.double-dash 212 EXISTS( 213 select 1) 214 ELSE NULL 215 ) as result 216 """ 217 218 query = \ 219 ''' 220 SELECT 221 ( 222 SELECT CASE field 223 WHEN 1 224 THEN -- comment's say that 225 # ^ source.sql comment.line.double-dash 226 EXISTS( 227 select 1) 228 ELSE NULL 229 ) as result 230 ''' 231 232 sql = 'SELECT * FROM foo -- bar baz' 233 # ^ source.sql 234 # ^ source.sql comment.line.double-dash 235 # ^ punctuation.definition.string.end.python - source.sql 236 237 238 # There are many variations of making a byte string 239 (b'', B'', br'', bR'', BR'', Br'', rb'', Rb'', RB'', rB'') 240 #^ storage.type.string 241 # ^ storage.type.string 242 # ^^ storage.type.string 243 # ^^ storage.type.string 244 # ^^ storage.type.string 245 # ^^ storage.type.string 246 # ^^ storage.type.string 247 # ^^ storage.type.string 248 # ^^ storage.type.string 249 # ^^ storage.type.string 250 251 # Bytes by defaut support placeholders and character escapes, but not unicode 252 b'This is a \n test, %s no unicode \uDEAD' 253 # <- storage.type.string 254 #^ string.quoted.single punctuation.definition.string.begin 255 # ^^ constant.character.escape 256 # ^^ constant.other.placeholder 257 # ^^^^^^ - constant 258 B'This is a \n test, %s no unicode \uDEAD' 259 # <- storage.type.string 260 #^ string.quoted.single punctuation.definition.string.begin 261 # ^^ constant.character.escape 262 # ^^ constant.other.placeholder 263 # ^^^^^^ - constant 264 b'''This is a \n test, %s no unicode \uDEAD''' 265 # <- storage.type.string 266 #^^^ string.quoted.single punctuation.definition.string.begin 267 # ^^ constant.character.escape 268 # ^^ constant.other.placeholder 269 # ^^^^^^ - constant 270 B'''This is a \n test, %s no unicode \uDEAD''' 271 # <- storage.type.string 272 #^^^ string.quoted.single punctuation.definition.string.begin 273 # ^^ constant.character.escape 274 # ^^ constant.other.placeholder 275 # ^^^^^^ - constant 276 277 # Uppercase R raw bytes don't allow anything 278 bR'This is a \n test, %s no unicode \uDEAD' 279 # <- storage.type.string 280 # ^ string.quoted.single punctuation.definition.string.begin 281 # ^^ - constant.character.escape 282 # ^^ - constant.other.placeholder 283 # ^^^^^^ - constant 284 BR'This is a \n test, %s no unicode \uDEAD' 285 # <- storage.type.string 286 # ^ string.quoted.single punctuation.definition.string.begin 287 # ^^ - constant.character.escape 288 # ^^ - constant.other.placeholder 289 # ^^^^^^ - constant 290 Rb'This is a \n test, %s no unicode \uDEAD' 291 # <- storage.type.string 292 # ^ string.quoted.single punctuation.definition.string.begin 293 # ^^ - constant.character.escape 294 # ^^ - constant.other.placeholder 295 # ^^^^^^ - constant 296 RB'This is a \n test, %s no unicode \uDEAD' 297 # <- storage.type.string 298 # ^ string.quoted.single punctuation.definition.string.begin 299 # ^^ - constant.character.escape 300 # ^^ - constant.other.placeholder 301 # ^^^^^^ - constant 302 bR'''This is a \n test, %s no unicode \uDEAD''' 303 # <- storage.type.string 304 # ^^^ string.quoted.single punctuation.definition.string.begin 305 # ^^ - constant.character.escape 306 # ^^ - constant.other.placeholder 307 # ^^^^^^ - constant 308 BR'''This is a \n test, %s no unicode \uDEAD''' 309 # <- storage.type.string 310 # ^^^ string.quoted.single punctuation.definition.string.begin 311 # ^^ - constant.character.escape 312 # ^^ - constant.other.placeholder 313 # ^^^^^^ - constant 314 Rb'''This is a \n test, %s no unicode \uDEAD''' 315 # <- storage.type.string 316 # ^^^ string.quoted.single punctuation.definition.string.begin 317 # ^^ - constant.character.escape 318 # ^^ - constant.other.placeholder 319 # ^^^^^^ - constant 320 RB'''This is a \n test, %s no unicode \uDEAD''' 321 # <- storage.type.string 322 # ^^^ string.quoted.single punctuation.definition.string.begin 323 # ^^ - constant.character.escape 324 # ^^ - constant.other.placeholder 325 # ^^^^^^ - constant 326 327 # Lowercase r raw bytes are interpreted as regex 328 br'This is a \n (test|with), %s no unicode \uDEAD' 329 # <- storage.type.string 330 # ^ string.quoted.single punctuation.definition.string.begin 331 # ^^ constant.character.escape.backslash.regexp 332 # ^ keyword.operator.or.regexp 333 # ^^ - constant 334 # ^^ constant.character.escape.backslash.regexp 335 # ^^^^ - constant 336 Br'This is a \n (test|with), %s no unicode \uDEAD' 337 # <- storage.type.string 338 # ^ string.quoted.single punctuation.definition.string.begin 339 # ^^ constant.character.escape.backslash.regexp 340 # ^ keyword.operator.or.regexp 341 # ^^ - constant 342 # ^^ constant.character.escape.backslash.regexp 343 # ^^^^ - constant 344 rb'This is a \n (test|with), %s no unicode \uDEAD' 345 # <- storage.type.string 346 # ^ string.quoted.single punctuation.definition.string.begin 347 # ^^ constant.character.escape.backslash.regexp 348 # ^ keyword.operator.or.regexp 349 # ^^ - constant 350 # ^^ constant.character.escape.backslash.regexp 351 # ^^^^ - constant 352 rB'This is a \n (test|with), %s no unicode \uDEAD' 353 # <- storage.type.string 354 # ^ string.quoted.single punctuation.definition.string.begin 355 # ^^ constant.character.escape.backslash.regexp 356 # ^ keyword.operator.or.regexp 357 # ^^ - constant 358 # ^^ constant.character.escape.backslash.regexp 359 # ^^^^ - constant 360 br'''This is a \n (test|with), %s no unicode \uDEAD''' 361 # <- storage.type.string 362 # ^^^ string.quoted.single punctuation.definition.string.begin 363 # ^^ constant.character.escape.backslash.regexp 364 # ^ keyword.operator.or.regexp 365 # ^^ - constant 366 # ^^ constant.character.escape.backslash.regexp 367 # ^^^^ - constant 368 Br'''This is a \n (test|with), %s no unicode \uDEAD''' 369 # <- storage.type.string 370 # ^^^ string.quoted.single punctuation.definition.string.begin 371 # ^^ constant.character.escape.backslash.regexp 372 # ^ keyword.operator.or.regexp 373 # ^^ - constant 374 # ^^ constant.character.escape.backslash.regexp 375 # ^^^^ - constant 376 rb'''This is a \n (test|with), %s no unicode \uDEAD''' 377 # <- storage.type.string 378 # ^^^ string.quoted.single punctuation.definition.string.begin 379 # ^^ constant.character.escape.backslash.regexp 380 # ^ keyword.operator.or.regexp 381 # ^^ - constant 382 # ^^ constant.character.escape.backslash.regexp 383 # ^^^^ - constant 384 rB'''This is a \n (test|with), %s no unicode \uDEAD''' 385 # <- storage.type.string 386 # ^^^ meta.string.python string.quoted.single punctuation.definition.string.begin 387 # ^^ constant.character.escape.backslash.regexp 388 # ^ keyword.operator.or.regexp 389 # ^^ - constant 390 # ^^ constant.character.escape.backslash.regexp 391 # ^^^^ - constant 392 393 datetime.strptime('2011227', '%Y%V%u') 394 # ^^^^^^^^ string.quoted.single.python 395 # ^^^^^^ constant.other.placeholder.python 396 datetime.strftime(datetime.now(), '%Y%V%uT') 397 # ^^^^^^^^^ string.quoted.single.python 398 # ^^^^^^ constant.other.placeholder.python 399 # ^ - constant.other.placeholder.python 400 401 '{0:%Y%m%d}'.format(datetime.date.today()) 402 # ^^^^^^^^^^ string.quoted.single.python 403 # ^^^^^^^^ constant.other.placeholder.python 404 # ^^^^^^ constant.other.format-spec.python 405 '{0:%Y-%m-%d}'.format(datetime.date.today()) 406 # ^^^^^^^^^^^^ string.quoted.single.python 407 # ^^^^^^^^^^ constant.other.placeholder.python 408 # ^^^^^^^^ constant.other.format-spec.python 409 '{0:%Y-%m-%dT}'.format(datetime.date.today()) 410 # ^^^^^^^^^^^^ string.quoted.single.python 411 # ^^^^^^^^^^^ constant.other.placeholder.python 412 # ^^^^^^^^^ constant.other.format-spec.python 413 '{0:T}'.format(datetime.date.today()) # This is legal but uninteresting 414 # ^^^^^ string.quoted.single.python 415 '{0:%Y}-{0:%m}-{0:%d}'.format(datetime.date.today()) 416 # ^^^^^^^^^^^^^^^^^^^ string.quoted.single.python 417 # ^^^^^ constant.other.placeholder.python 418 # ^^^ constant.other.format-spec.python 419 # ^ - constant.other.placeholder.python 420 # ^^^^^^ constant.other.placeholder.python 421 # ^^ constant.other.format-spec.python 422 # ^ - constant.other.placeholder.python 423 # ^^^^^^ constant.other.placeholder.python 424 # ^^ constant.other.format-spec.python 425 '{0:%Y}-{0:%m 426 # ^^^^^^^^^^^ string.quoted.single.python 427 # ^^^^^ constant.other.placeholder.python 428 # ^^^ constant.other.format-spec.python 429 # ^^^^ - constant.other.placeholder.python 430 # ^ invalid.illegal.unclosed-string.python 431 '{0:%Y}-{0:% 432 # ^^^^^^^^^^^ string.quoted.single.python 433 # ^^^^^ constant.other.placeholder.python 434 # ^^^ constant.other.format-spec.python 435 # ^^^^^ - constant.other.placeholder.python 436 # ^ invalid.illegal.unclosed-string.python 437 438 x = "hello \ 439 # ^^^^^^^^^ string.quoted.double.python - invalid.illegal.unclosed-string.python, \ 440 # ^ punctuation.separator.continuation.line.python, \ 441 world" 442 #^^^^^ string.quoted.double.python 443 # ^ - string.quoted.double.python 444 # ^ punctuation.definition.string.end.python 445 446 x = 'hello \ 447 # ^^^^^^^^^ string.quoted.single.python - invalid.illegal.unclosed-string.python, \ 448 # ^ punctuation.separator.continuation.line.python, \ 449 world' 450 #^^^^^ string.quoted.single.python 451 # ^ - string.quoted.single.python 452 # ^ punctuation.definition.string.end.python 453 454 x = 'hello\s world' 455 # ^^ - punctuation.separator.continuation.line.python 456 # ^^^^^^^^ - invalid.illegal.unexpected-text.python 457 458 sql = "SELECT `name` FROM `users` \ 459 WHERE `password` LIKE 'abc'" 460 #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double source.sql 461 # ^ punctuation.definition.string.end.python 462 463 sql = Ur"SELECT `name` FROM `users` \ 464 WHERE `password` LIKE 'abc'" 465 #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double source.sql 466 # ^ punctuation.definition.string.end.python 467 468 sql = b'just some \ 469 # ^^^^^^^^^^^^^ string.quoted.single.python - invalid.illegal.unclosed-string.python, \ 470 # ^ punctuation.separator.continuation.line.python, \ 471 string' 472 #^^^^^^^^^^ string.quoted.single 473 # ^ punctuation.definition.string.end.python 474 475 # https://docs.python.org/3/library/string.html#formatspec 476 "First, thou shalt count to {0}" # References first positional argument 477 # ^^^ constant.other.placeholder.python 478 "Bring me a {}" # Implicitly references the first positional argument 479 # ^^ constant.other.placeholder.python 480 "From {} to {}" # Same as "From {0} to {1}" 481 # ^^ constant.other.placeholder.python 482 # ^^^^ - constant.other.placeholder.python 483 # ^^ constant.other.placeholder.python 484 "My quest is {name}" # References keyword argument 'name' 485 # ^^^^^^ constant.other.placeholder.python 486 "Weight in tons {0.weight}" # 'weight' attribute of first positional arg 487 # ^^^^^^^^^^ constant.other.placeholder.python 488 "Units destroyed: {players[0]}" # First element of keyword argument 'players'. 489 # ^^^^^^^^^^^^ constant.other.placeholder.python 490 "Harold's a clever {0!s}" # Calls str() on the argument first 491 # ^^^^^ constant.other.placeholder.python 492 # ^^ storage.modifier.conversion.python 493 "Bring out the holy {name!r}" # Calls repr() on the argument first 494 # ^^^^^^^^ constant.other.placeholder.python 495 "More {!a}" # Calls ascii() on the argument first 496 # ^^^^ constant.other.placeholder.python 497 "More {!a: <10s}" # Calls ascii() on the argument first, then formats 498 # ^^^^^^^^^^ constant.other.placeholder.python 499 "Escaped {{0}}" # outputs: "Escaped {0}" 500 # ^^^^^ - constant.other.placeholder.python 501 # ^^ constant.character.escape.python 502 # ^^ constant.character.escape.python 503 "Escaped {{}} {} {}" # outputs: "Escaped {} arg1 arg2" 504 # ^^^^ constant.character.escape.python - constant.other.placeholder.python 505 # ^^ constant.other.placeholder.python 506 # ^ - constant.other.placeholder.python 507 # ^^ constant.other.placeholder.python 508 509 datetime.datetime.utcnow().strftime("%Y%m%d%H%M") 510 # ^^^^^^^^^^ constant.other.placeholder 511 512 "My String %% %s" 513 # ^^ constant.other.placeholder 514 # ^^ constant.other.placeholder 515 516 "My String %(s)s %s" 517 # ^^^^^ constant.other.placeholder 518 # ^ variable.other.placeholder 519 # ^^ constant.other.placeholder 520 521 "Testing {:,.2f}".format(1000) 522 # ^^^^^^^ constant.other.placeholder 523 # ^ punctuation.definition.placeholder.begin 524 # ^ punctuation.definition.placeholder.end 525 526 "Testing {0:>9,}".format(1000) 527 # ^^^^^^^ constant.other.placeholder 528 529 "Testing {:j^9,}".format(1000) 530 # ^^^^^^^ constant.other.placeholder 531 # ^^^^^ constant.other.format-spec 532 533 "result: {value:{width}.{precision}}" 534 # ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant.other.placeholder 535 # ^^^^^^^^^^^^^^^^^^^^ meta.format-spec.python 536 # ^ punctuation.definition.placeholder.begin 537 # ^^^^^^^ constant.other.placeholder constant.other.placeholder 538 # ^ punctuation.definition.placeholder.begin 539 # ^^^^^^^^^^^ constant.other.placeholder constant.other.placeholder 540 # ^^ punctuation.definition.placeholder.end 541 542 a=["aaaa{", "bbbb{"] 543 # ^ - constant.other.placeholder 544 # ^ punctuation.definition.string.end.python 545 546 foo = "{text{" # Comment 547 # ^^^^^^ - constant.other.placeholder 548 # ^ punctuation.definition.string.end 549 bar = "}}" # Comment 550 # ^^ constant.character.escape 551 552 f"string" 553 # <- storage.type.string 554 #^^^^^^^^ string.quoted.double 555 556 RF"""string""" 557 #^^ storage.type.string - string 558 # ^^^^^^^^^^^^ meta.string.interpolated string.quoted.double.block 559 560 F'''string''' 561 # <- storage.type.string 562 #^^^^^^^^^^^^ meta.string.interpolated string.quoted.single.block 563 564 rf'string' 565 #^^ storage.type.string - string 566 # ^^^^^^^^ meta.string.interpolated string.quoted.single 567 568 rf'\r\n' f'\r\n' Rf'\r\n' 569 # ^^^^ source.regexp constant.character.escape.backslash.regexp 570 # ^^^^ constant.character.escape.python 571 # ^^^^ - constant 572 573 rf"\r\n" f"\r\n" Rf'\r\n' 574 # ^^^^ source.regexp constant.character.escape.backslash.regexp 575 # ^^^^ constant.character.escape.python 576 # ^^^^ - constant 577 578 expr = fr"^\s*({label}|{notlabel})" 579 # ^^^^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated.python 580 # ^ meta.string.interpolated.python string.quoted.double.python source.regexp.python keyword.control.anchor.regexp 581 # ^ source.regexp.python meta.group.regexp punctuation.definition.group.begin.regexp 582 # ^^^^^^^ source.python meta.string.interpolated.python meta.interpolation.python 583 # ^^^^^ source.python.embedded meta.qualified-name.python meta.generic-name.python 584 # ^ source.regexp.python meta.group.regexp punctuation.definition.group.end.regexp 585 586 line = re.sub(rf" ?\{{\\i.?\}}({x})\{{\\i.?\}}", r"\1", line) 587 # ^^^^^ constant.character.escape.backslash.regexp 588 # ^^ constant.character.escape.python 589 # ^^^ constant.character.escape.backslash.regexp 590 # ^^ constant.character.escape.python 591 # ^ punctuation.section.interpolation.begin.python 592 593 f"\{{{x}\}} test" 594 # ^ invalid.deprecated.character.escape.python 595 # ^^ constant.character.escape.python 596 # ^ punctuation.section.interpolation.begin.python 597 598 f"{something}" 599 #^^^^^^^^^^^^ meta.string.interpolated 600 # <- storage.type.string 601 #^ punctuation.definition.string.begin 602 # ^ punctuation.section.interpolation.begin 603 # ^ punctuation.section.interpolation.end 604 # ^ punctuation.definition.string.end 605 # ^^^^^^^^^ source source.python.embedded 606 # ^ source - meta, string, source source 607 608 f"{True!a:02f}" 609 #^^^^^^^^^^^^^^ meta.string.interpolated 610 # ^ - source source.python.embedded 611 # ^^^^ source source.python.embedded constant.language 612 # ^^^^^^^ - source source.python.embedded 613 # ^^ storage.modifier.conversion - constant.other.format-spec 614 # ^^^^ constant.other.format-spec 615 # ^ punctuation.section.interpolation.end 616 # ^ punctuation.definition.string.end 617 # ^ source - meta, string, source source 618 619 f"result: {value:{width}.{precision}}\n" 620 # ^ punctuation.section.interpolation.begin.python - source source 621 # ^^^^^ source source.python.embedded 622 # ^^ - source source 623 # ^ punctuation.section.interpolation.begin.python 624 # ^^^^^ source source.python.embedded 625 # ^ punctuation.section.interpolation.end.python 626 # ^ - source source 627 # ^ punctuation.section.interpolation.begin.python 628 # ^^^^^^^^^ source source.python.embedded 629 # ^^ punctuation.section.interpolation.end.python - source source 630 # ^^ constant.character.escape 631 # ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.interpolation.python 632 # ^^^^^^^^^^^^^^^^^^^^ meta.format-spec.python 633 # ^^^^^^ - meta.interpolation.python meta.interpolation.python 634 # ^^^^^^^ meta.interpolation.python meta.interpolation.python 635 # ^ - meta.interpolation.python meta.interpolation.python 636 # ^^^^^^^^^^^ meta.interpolation.python meta.interpolation.python 637 # ^^^ - meta.interpolation.python meta.interpolation.python 638 rf"{value:{width!s:d}}" 639 # <- storage.type.string.python - string 640 # ^^^^^^^^^^^^^^^^^^^^^ meta.string.interpolated 641 # ^^^^^ source source.python.embedded 642 # ^^ storage.modifier.conversion 643 # ^^ constant.other.format-spec 644 645 F""" {} {\} } 646 #^^^^^^^^^^^ meta.string.interpolated 647 #^^^ punctuation.definition.string.begin 648 # ^^ invalid.illegal.empty-expression 649 # ^ invalid.illegal.backslash-in-fstring 650 # ^ invalid.illegal.stray-brace 651 """ 652 653 fr''' 654 # ^ - invalid 655 ''' 656 657 # Most of these were inspired by 658 # https://github.com/python/cpython/commit/9a4135e939bc223f592045a38e0f927ba170da32 659 f'{x=:}' 660 # ^ storage.modifier.debug.python 661 f'{x=:.2f}' 662 # ^ storage.modifier.debug.python 663 f'{x=!r}' 664 # ^ storage.modifier.debug.python 665 f'{x=!a}' 666 # ^ storage.modifier.debug.python 667 f'{x=!s:*^20}' 668 # ^ storage.modifier.debug.python 669 # ^^ storage.modifier.conversion.python 670 # ^^^^^ meta.format-spec.python 671 f'{"Σ"=}' 672 # ^ storage.modifier.debug.python 673 f'{0==1}' 674 # ^^ -storage.modifier.debug.python 675 f'{0!=1}' 676 # ^ -storage.modifier.debug.python 677 f'{0<=1}' 678 # ^ -storage.modifier.debug.python 679 f'{0>=1}' 680 # ^ -storage.modifier.debug.python 681 f'{f(a="3=")}' 682 # ^^^^ -storage.modifier.debug.python 683 684 f" { 685 % ^ invalid.illegal.unclosed-string 686 # TODO make this test pass 687 }" 688 689 f' \ 690 {1 + 2!a:02f}' 691 #^^^^^^^^^^^^^^ meta.string.interpolated 692 # ^^^^^ source source.python.embedded 693 694 f"{d for d in range(10)}" # yes, this doesn't make sense 695 # ^^^ keyword.control.loop.for.generator.python 696 697 f' 698 # ^ invalid.illegal.unclosed-string 699 700 701 # <- - meta 702 # this test is to ensure we're not matching anything here anymore