2269 lines
80 KiB
YAML
2269 lines
80 KiB
YAML
%YAML 1.2
|
|
---
|
|
name: Python
|
|
file_extensions:
|
|
- py
|
|
- py3
|
|
- pyw
|
|
- pyi
|
|
- pyx
|
|
- pyx.in
|
|
- pxd
|
|
- pxd.in
|
|
- pxi
|
|
- pxi.in
|
|
- rpy
|
|
- cpy
|
|
- SConstruct
|
|
- Sconstruct
|
|
- sconstruct
|
|
- SConscript
|
|
- gyp
|
|
- gypi
|
|
- Snakefile
|
|
- vpy
|
|
- wscript
|
|
- bazel
|
|
- bzl
|
|
first_line_match: ^#!\s*/.*\bpython(\d(\.\d)?)?\b
|
|
scope: source.python
|
|
|
|
variables:
|
|
# We support unicode here because Python 3 is the future
|
|
identifier_continue: '[[:alnum:]_]'
|
|
identifier: '\b[[:alpha:]_]{{identifier_continue}}*\b'
|
|
identifier_constant: '\b(?:[\p{Lu}_][\p{Lu}_\d]*)?[\p{Lu}]{2,}[\p{Lu}_\d]*\b' # require 2 consecutive upper-case letters
|
|
digits: (?:\d+(?:_\d+)*)
|
|
exponent: (?:[eE][-+]?{{digits}})
|
|
path: '({{identifier}}[ ]*\.[ ]*)*{{identifier}}'
|
|
sql_indicator: \s*(?:SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER|WITH)\b
|
|
illegal_names: (?:and|as|assert|break|class|continue|def|del|elif|else|except|finally|for|from|global|if|import|in|is|lambda|not|or|pass|raise|return|try|while|with|yield)
|
|
format_spec: |-
|
|
(?x:
|
|
(?:.? [<>=^])? # fill align
|
|
[ +-]? # sign
|
|
\#? # alternate form
|
|
# technically, octal and hexadecimal integers are also supported as 'width', but rarely used
|
|
\d* # width
|
|
,? # thousands separator
|
|
(?:\.\d+)? # precision
|
|
[bcdeEfFgGnosxX%]? # type
|
|
)
|
|
strftime_spec: '(?:%(?:[aAwdbBGmyYHIpMSfzZjuUVWcxX%]|-[dmHIMSj]))'
|
|
# This can be used in look-aheads to parse simple expressions.
|
|
# Can't be recursive, because sregex doesn't support that,
|
|
# so we're skipping parentheses.
|
|
# Can't parse multiple lines as well, for obvious reasons
|
|
simple_expression: |-
|
|
(?x:
|
|
\s+ # whitespace
|
|
| [urfb]*"(?:\\.|[^"])*" # strings
|
|
| [urfb]*'(?:\\.|[^'])*' # ^
|
|
| [\d.ej]+ # numerics
|
|
| [+*/%@-] | // | and | or # operators
|
|
| {{path}} # a path
|
|
)*
|
|
|
|
|
|
contexts:
|
|
main:
|
|
- include: statements
|
|
|
|
statements:
|
|
- include: docstrings
|
|
- include: line-statements
|
|
- include: block-statements
|
|
- include: classes
|
|
- include: functions
|
|
- include: modifiers
|
|
- include: assignments
|
|
- match: ;
|
|
scope: punctuation.terminator.statement.python
|
|
- include: expression-as-a-statement
|
|
|
|
line-statements:
|
|
- include: imports
|
|
- include: decorators
|
|
- match: \b(raise)\b
|
|
scope: keyword.control.flow.raise.python
|
|
push:
|
|
- meta_scope: meta.statement.raise.python
|
|
- include: line-continuation-or-pop
|
|
- match: \b(from)\b
|
|
scope: keyword.control.flow.raise.from.python
|
|
set:
|
|
- meta_scope: meta.statement.raise.python
|
|
- include: line-continuation-or-pop
|
|
- include: expression-in-a-statement
|
|
- include: expression-in-a-statement
|
|
- match: \b(assert)\b
|
|
scope: keyword.control.flow.assert.python
|
|
- match: \b(del)\b
|
|
scope: keyword.other.del.python
|
|
- match: \b(print)\b(?! *([,.\]}]))
|
|
scope: keyword.other.print.python
|
|
- match: \b(exec)\b(?! *($|[,.()\]}]))
|
|
scope: keyword.other.exec.python
|
|
- match: \b(return)\b
|
|
scope: keyword.control.flow.return.python
|
|
- match: \b(break)\b
|
|
scope: keyword.control.flow.break.python
|
|
- match: \b(continue)\b
|
|
scope: keyword.control.flow.continue.python
|
|
- match: \b(pass)\b
|
|
scope: keyword.control.flow.pass.python
|
|
|
|
imports:
|
|
- match: \b(import)\b
|
|
scope: keyword.control.import.python
|
|
push:
|
|
- imports-import-body
|
|
- expect-absolute-import
|
|
- match: \b(from)\b
|
|
scope: keyword.control.import.from.python
|
|
push:
|
|
- imports-from-body
|
|
- maybe-relative-import
|
|
|
|
imports-import-body:
|
|
- meta_scope: meta.statement.import.python
|
|
- include: line-continuation-or-pop
|
|
- match: ','
|
|
scope: punctuation.separator.import-list.python
|
|
push: expect-absolute-import
|
|
- match: (?=\bas\b)
|
|
set: import-alias-list
|
|
- include: qualified-name
|
|
- match: (?=\S)
|
|
pop: true
|
|
|
|
imports-from-body:
|
|
- meta_scope: meta.statement.import.python
|
|
- meta_content_scope: meta.import-source.python
|
|
- include: line-continuation-or-pop
|
|
- match: (?=\bas\b)
|
|
set: import-alias-list
|
|
- match: (?=\bimport\b)
|
|
set:
|
|
- meta_include_prototype: false
|
|
- match: import
|
|
scope: keyword.control.import.python
|
|
set: imports-from-import-body
|
|
- match: '{{illegal_names}}\b'
|
|
scope: meta.import-path.python invalid.illegal.name.python
|
|
- match: '{{identifier}}'
|
|
scope: meta.import-path.python meta.import-name.python
|
|
- match: \s*(\.) *(?={{identifier}}|$)
|
|
captures:
|
|
0: meta.import-path.python
|
|
1: punctuation.accessor.dot.python
|
|
- match: \s*(\. *\S+) # matches and consumes the remainder of "abc.123" or "abc.+"
|
|
captures:
|
|
0: meta.import-path.python
|
|
1: invalid.illegal.name.python
|
|
- match: (?=\S)
|
|
pop: true
|
|
|
|
imports-from-import-body:
|
|
- meta_scope: meta.statement.import.python
|
|
- include: line-continuation-or-pop
|
|
- match: (?=\()
|
|
set:
|
|
- meta_include_prototype: false
|
|
- match: \(
|
|
scope: punctuation.section.import-list.begin.python
|
|
set:
|
|
- meta_scope: meta.statement.import.python meta.import-list.python
|
|
- match: \)
|
|
scope: punctuation.section.import-list.end.python
|
|
pop: true
|
|
- include: comments
|
|
- include: import-name-list
|
|
- match: (?=\S)
|
|
set: import-alias-list
|
|
|
|
import-alias-list:
|
|
- meta_content_scope: meta.statement.import.python
|
|
- include: line-continuation-or-pop
|
|
- include: import-name-list
|
|
|
|
import-name-list:
|
|
- match: ','
|
|
scope: punctuation.separator.import-list.python
|
|
- match: \*
|
|
scope: constant.language.import-all.python
|
|
- match: \b(as)\b
|
|
scope: keyword.control.import.as.python
|
|
- include: name
|
|
- match: '[^\s,)]+'
|
|
scope: invalid.illegal.name.import.python
|
|
|
|
expect-absolute-import:
|
|
- include: line-continuation-or-pop
|
|
- match: \.+
|
|
scope: invalid.illegal.unexpected-relative-import.python
|
|
- match: (?=\S)
|
|
pop: true
|
|
|
|
maybe-relative-import:
|
|
- include: line-continuation-or-pop
|
|
- match: \.+
|
|
scope: meta.import-path.python keyword.control.import.relative.python
|
|
- match: (?=\S)
|
|
pop: true
|
|
|
|
block-statements:
|
|
# async for ... in ...:
|
|
- match: \b(async +)?(for)\b
|
|
captures:
|
|
1: storage.modifier.async.python
|
|
2: keyword.control.loop.for.python
|
|
push:
|
|
- meta_scope: meta.statement.loop.for.python
|
|
- include: line-continuation-or-pop
|
|
- match: \bin\b
|
|
scope: keyword.control.loop.for.in.python
|
|
set:
|
|
- meta_content_scope: meta.statement.loop.for.python
|
|
- include: line-continuation-or-pop
|
|
- match: ':(?!=)'
|
|
scope: meta.statement.loop.for.python punctuation.section.block.loop.for.python
|
|
pop: true
|
|
- include: expression-in-a-statement
|
|
- match: ':(?!=)'
|
|
scope: invalid.illegal.missing-in.python
|
|
pop: true
|
|
- include: target-list
|
|
# async with ... as ...:
|
|
- match: \b(async +)?(with)\b
|
|
captures:
|
|
1: storage.modifier.async.python
|
|
2: keyword.control.flow.with.python
|
|
push: with-body
|
|
# except ... as ...:
|
|
- match: \bexcept\b
|
|
scope: keyword.control.exception.catch.python
|
|
push:
|
|
- meta_scope: meta.statement.exception.catch.python
|
|
- include: line-continuation-or-pop
|
|
- match: ':(?!=)'
|
|
scope: punctuation.section.block.exception.catch.python
|
|
pop: true
|
|
- match: '\bas\b'
|
|
scope: keyword.control.exception.catch.as.python
|
|
set:
|
|
- meta_content_scope: meta.statement.exception.catch.python
|
|
- include: line-continuation-or-pop
|
|
- match: ':'
|
|
scope: meta.statement.exception.catch.python punctuation.section.block.exception.catch.python
|
|
pop: true
|
|
- include: name
|
|
- include: target-list
|
|
- match: \bif\b
|
|
scope: keyword.control.conditional.if.python
|
|
push:
|
|
- meta_scope: meta.statement.conditional.if.python
|
|
- include: line-continuation-or-pop
|
|
- match: ':(?!=)'
|
|
scope: punctuation.section.block.conditional.if.python
|
|
pop: true
|
|
- include: expression-in-a-statement
|
|
- match: \bwhile\b
|
|
scope: keyword.control.loop.while.python
|
|
push:
|
|
- meta_scope: meta.statement.loop.while.python
|
|
- include: line-continuation-or-pop
|
|
- match: ':(?!=)'
|
|
scope: punctuation.section.block.loop.while.python
|
|
pop: true
|
|
- include: expression-in-a-statement
|
|
- match: \b(else)\b(?:\s*(:))?
|
|
scope: meta.statement.conditional.else.python
|
|
captures:
|
|
1: keyword.control.conditional.else.python
|
|
2: punctuation.section.block.conditional.else.python
|
|
- match: \b(try)\b(?:\s*(:))?
|
|
scope: meta.statement.exception.try.python
|
|
captures:
|
|
1: keyword.control.exception.try.python
|
|
2: punctuation.section.block.exception.try.python
|
|
- match: \b(finally)\b(?:\s*(:))?
|
|
scope: meta.statement.exception.finally.python
|
|
captures:
|
|
1: keyword.control.exception.finally.python
|
|
2: punctuation.section.block.exception.finally.python
|
|
- match: \belif\b
|
|
scope: keyword.control.conditional.elseif.python
|
|
push:
|
|
- meta_scope: meta.statement.conditional.elseif.python
|
|
- match: ':(?!=)'
|
|
scope: punctuation.section.block.conditional.elseif.python
|
|
pop: true
|
|
- match: $\n?
|
|
pop: true
|
|
- include: expression-in-a-statement
|
|
|
|
with-body:
|
|
- meta_scope: meta.statement.with.python
|
|
- include: line-continuation-or-pop
|
|
- match: \b(as)\b
|
|
scope: keyword.control.flow.with.as.python
|
|
set: with-as
|
|
- match: ':(?!=)'
|
|
scope: punctuation.section.block.with.python
|
|
pop: true
|
|
- match: ','
|
|
scope: punctuation.separator.with-resources.python
|
|
- include: expression-in-a-statement
|
|
|
|
with-as:
|
|
- meta_scope: meta.statement.with.python
|
|
- include: line-continuation-or-pop
|
|
- match: ':'
|
|
scope: punctuation.section.block.with.python
|
|
pop: true
|
|
- match: ','
|
|
scope: punctuation.separator.with-resources.python
|
|
set: with-body
|
|
- include: name
|
|
- include: groups
|
|
- include: lists
|
|
|
|
expressions-common:
|
|
- include: comments
|
|
- include: constants
|
|
- include: numbers
|
|
- include: yields
|
|
- include: operators
|
|
- include: lambda
|
|
- match: \b(await)\b
|
|
scope: keyword.other.await.python
|
|
- include: inline-if
|
|
- include: strings
|
|
- include: function-calls
|
|
- include: item-access
|
|
- include: lists
|
|
- include: dictionaries-and-sets
|
|
- include: tuples
|
|
- include: groups
|
|
- match: \)
|
|
scope: invalid.illegal.stray.brace.round.python
|
|
- match: \]
|
|
scope: invalid.illegal.stray.brace.square.python
|
|
- match: \}
|
|
scope: invalid.illegal.stray.brace.curly.python
|
|
- include: line-continuation
|
|
|
|
# Always include these last and only one at a time!
|
|
expression-as-a-statement:
|
|
- include: expressions-common
|
|
- include: qualified-name
|
|
|
|
expression-in-a-statement:
|
|
# Differs from expression-as-a-statement in that:
|
|
# - invalid-name matches will pop the current context
|
|
# - assignment expressions
|
|
- include: expressions-common
|
|
- include: illegal-names-pop
|
|
- include: qualified-name
|
|
- include: assignment-expression
|
|
|
|
expression-in-a-group: # Always include this last!
|
|
# Differs from expression-in-a-statement in that:
|
|
# - accessor matching continues into the next line
|
|
- include: expression-in-a-statement
|
|
- match: '(\.) *(?={{identifier}})'
|
|
captures:
|
|
1: punctuation.accessor.dot.python
|
|
push:
|
|
- include: magic-function-names
|
|
- include: magic-variable-names
|
|
- include: illegal-names
|
|
- include: generic-names
|
|
- match: ''
|
|
pop: true
|
|
|
|
after-expression:
|
|
# direct function call
|
|
- match: '\s*(\()'
|
|
captures:
|
|
1: punctuation.section.arguments.begin.python
|
|
push: [function-call-arguments, allow-unpack-operators]
|
|
# item access
|
|
- match: '\s*(\[)'
|
|
captures:
|
|
1: meta.item-access.python punctuation.section.brackets.begin.python
|
|
push:
|
|
- meta_content_scope: meta.item-access.arguments.python
|
|
- match: \]
|
|
scope: meta.item-access.python punctuation.section.brackets.end.python
|
|
pop: true
|
|
- include: illegal-assignment-expression
|
|
- match: ':'
|
|
scope: punctuation.separator.slice.python
|
|
- include: expression-in-a-group
|
|
# indirect function call following attribute access
|
|
- include: function-calls
|
|
# arbitrary attribute access
|
|
- match: '\s*(\.)'
|
|
captures:
|
|
1: punctuation.accessor.dot.python
|
|
push:
|
|
- include: magic-function-names
|
|
- include: magic-variable-names
|
|
- include: illegal-names
|
|
- include: generic-names
|
|
- match: ''
|
|
pop: true
|
|
- match: ''
|
|
pop: true
|
|
|
|
comments:
|
|
- match: "#"
|
|
scope: punctuation.definition.comment.python
|
|
push:
|
|
- meta_scope: comment.line.number-sign.python
|
|
- match: \n
|
|
pop: true
|
|
|
|
constants:
|
|
- match: \b(None|True|False|Ellipsis|NotImplemented|__debug__)\b
|
|
scope: constant.language.python
|
|
- match: \.{3}(?!\w)
|
|
scope: constant.language.python
|
|
|
|
numbers:
|
|
# https://docs.python.org/3/reference/lexical_analysis.html#numeric-literals
|
|
# hexadecimal
|
|
- match: \b(0[xX])(\h*)([lL]) # py2
|
|
scope: meta.number.integer.hexadecimal.python
|
|
captures:
|
|
1: constant.numeric.base.python
|
|
2: constant.numeric.value.python
|
|
3: constant.numeric.suffix.python
|
|
- match: \b(0[xX])((?:_?\h)+)
|
|
scope: meta.number.integer.hexadecimal.python
|
|
captures:
|
|
1: constant.numeric.base.python
|
|
2: constant.numeric.value.python
|
|
# octal
|
|
- match: \b(0[oO]?)((?=[oO]|[0-7])[0-7]*)([lL]) # py2
|
|
scope: meta.number.integer.octal.python
|
|
captures:
|
|
1: constant.numeric.base.python
|
|
2: constant.numeric.value.python
|
|
3: constant.numeric.suffix.python
|
|
- match: \b(0)([0-7]+) # py2
|
|
scope: meta.number.integer.octal.python
|
|
captures:
|
|
1: constant.numeric.base.python
|
|
2: constant.numeric.value.python
|
|
- match: \b(0[oO])((?:_?[0-7])+)
|
|
scope: meta.number.integer.octal.python
|
|
captures:
|
|
1: constant.numeric.base.python
|
|
2: constant.numeric.value.python
|
|
# binary
|
|
- match: \b(0[bB])([01]*)([lL]) # py2
|
|
scope: meta.number.integer.binary.python
|
|
captures:
|
|
1: constant.numeric.base.python
|
|
2: constant.numeric.value.python
|
|
3: constant.numeric.suffix.python
|
|
- match: \b(0[bB])((?:_?[01])*)
|
|
scope: meta.number.integer.binary.python
|
|
captures:
|
|
1: constant.numeric.base.python
|
|
2: constant.numeric.value.python
|
|
# complex
|
|
- match: |-
|
|
(?x)
|
|
(
|
|
# 1.j, 1.1j, 1.1e1j, 1.1e-1j, 1.e1j, 1.e-1 | 1e1j, 1e-1j
|
|
\b{{digits}} (\.)? {{digits}}? {{exponent}}?
|
|
# .1j, .1e1j, .1e-1j
|
|
| (\.) {{digits}} {{exponent}}?
|
|
)
|
|
([jJ])
|
|
scope: meta.number.imaginary.decimal.python
|
|
captures:
|
|
1: constant.numeric.value.python
|
|
2: punctuation.separator.decimal.python
|
|
3: punctuation.separator.decimal.python
|
|
4: constant.numeric.suffix.python
|
|
# floating point
|
|
- match: |-
|
|
(?x:
|
|
# 1., 1.1, 1.1e1, 1.1e-1, 1.e1, 1.e-1 | 1e1, 1e-1
|
|
\b{{digits}} (?: (\.) {{digits}}? {{exponent}}? | {{exponent}} )
|
|
# .1, .1e1, .1e-1
|
|
| (\.) {{digits}} {{exponent}}?
|
|
)
|
|
scope: meta.number.float.decimal.python constant.numeric.value.python
|
|
captures:
|
|
1: punctuation.separator.decimal.python
|
|
2: punctuation.separator.decimal.python
|
|
# integer
|
|
- match: \b([1-9]\d*|0)([lL])\b # py2
|
|
scope: meta.number.integer.decimal.python
|
|
captures:
|
|
1: constant.numeric.value.python
|
|
2: constant.numeric.suffix.python
|
|
- match: \b([1-9][\d_]*|0)\b
|
|
scope: meta.number.integer.decimal.python constant.numeric.value.python
|
|
|
|
modifiers:
|
|
- match: \b(?:(global)|(nonlocal))\b
|
|
captures:
|
|
1: storage.modifier.global.python
|
|
2: storage.modifier.nonlocal.python
|
|
push:
|
|
- include: line-continuation-or-pop
|
|
- match: ','
|
|
scope: punctuation.separator.storage-list.python
|
|
- include: name
|
|
- match: \S+
|
|
scope: invalid.illegal.name.storage.python
|
|
|
|
yields:
|
|
- match: \b(yield)(?:\s+(from))?\b
|
|
captures:
|
|
1: keyword.control.flow.yield.python
|
|
2: keyword.control.flow.yield-from.python
|
|
|
|
assignment-expression:
|
|
- match: :=
|
|
scope: keyword.operator.assignment.inline.python
|
|
|
|
illegal-assignment-expression:
|
|
- match: :=
|
|
scope: invalid.illegal.not-allowed-here.python
|
|
|
|
assignments:
|
|
- include: illegal-assignment-expression
|
|
- match: ':'
|
|
scope: punctuation.separator.annotation.variable.python
|
|
- match: \+=|-=|\*=|/=|//=|%=|@=|&=|\|=|\^=|>>=|<<=|\*\*=
|
|
scope: keyword.operator.assignment.augmented.python
|
|
- match: '=(?!=)'
|
|
scope: keyword.operator.assignment.python
|
|
|
|
operators:
|
|
- match: <>
|
|
scope: invalid.deprecated.operator.python
|
|
- match: <\=|>\=|\=\=|<|>|\!\=
|
|
scope: keyword.operator.comparison.python
|
|
- match: \+|\-|\*|\*\*|/|//|%|<<|>>|&|\||\^|~
|
|
scope: keyword.operator.arithmetic.python
|
|
- match: \b(and|in|is|not|or)\b
|
|
comment: keyword operators that evaluate to True or False
|
|
scope: keyword.operator.logical.python
|
|
- match: '@'
|
|
scope: keyword.operator.matrix.python
|
|
- match: ','
|
|
scope: punctuation.separator.sequence.python
|
|
|
|
allow-unpack-operators:
|
|
# Match unpacking operators, if present
|
|
- include: comments
|
|
- match: \*{3,}
|
|
scope: invalid.illegal.syntax.python
|
|
pop: true
|
|
- match: \*\*
|
|
scope: keyword.operator.unpacking.mapping.python
|
|
pop: true
|
|
- match: \*
|
|
scope: keyword.operator.unpacking.sequence.python
|
|
pop: true
|
|
- match: (?=\S)
|
|
pop: true
|
|
|
|
classes:
|
|
- match: '^\s*(class)\b'
|
|
captures:
|
|
1: keyword.declaration.class.python
|
|
push:
|
|
- meta_scope: meta.class.python
|
|
- include: line-continuation-or-pop
|
|
- match: ':'
|
|
scope: punctuation.section.class.begin.python
|
|
pop: true
|
|
- match: "(?={{identifier}})"
|
|
push:
|
|
- meta_content_scope: entity.name.class.python
|
|
- include: entity-name-class
|
|
- match: ''
|
|
pop: true
|
|
- match: \(
|
|
scope: punctuation.section.inheritance.begin.python
|
|
set:
|
|
- meta_scope: meta.class.inheritance.python
|
|
- match: \)
|
|
scope: punctuation.section.inheritance.end.python
|
|
set:
|
|
- include: line-continuation-or-pop
|
|
- match: ':'
|
|
scope: meta.class.python punctuation.section.class.begin.python
|
|
pop: true
|
|
- match: (?=\S)
|
|
pop: true
|
|
- match: ':'
|
|
scope: invalid.illegal.no-closing-parens.python
|
|
pop: true
|
|
- match: ','
|
|
scope: punctuation.separator.inheritance.python
|
|
- include: illegal-names-pop
|
|
- match: ({{identifier}}) *(=)
|
|
captures:
|
|
1: variable.parameter.class-inheritance.python
|
|
2: keyword.operator.assignment.python
|
|
- match: (?={{path}})
|
|
push:
|
|
- meta_scope: entity.other.inherited-class.python
|
|
- match: '{{identifier}}(?: *(\.) *)?'
|
|
captures:
|
|
1: punctuation.accessor.dot.python
|
|
- match: ''
|
|
pop: true
|
|
- include: expression-in-a-group
|
|
|
|
functions:
|
|
- match: '^\s*(?:(async)\s+)?(def)\b'
|
|
captures:
|
|
1: keyword.declaration.async.python
|
|
2: keyword.declaration.function.python
|
|
push:
|
|
- meta_scope: meta.function.python
|
|
- include: line-continuation-or-pop
|
|
- match: ':'
|
|
scope: punctuation.section.function.begin.python
|
|
pop: true
|
|
- match: "(?={{identifier}})"
|
|
push:
|
|
- meta_content_scope: entity.name.function.python
|
|
- include: entity-name-function
|
|
- match: ''
|
|
pop: true
|
|
- match: '(?=\()'
|
|
set:
|
|
- match: \(
|
|
scope: meta.function.parameters.python punctuation.section.parameters.begin.python
|
|
set: [function-parameters, allow-unpack-operators]
|
|
|
|
function-parameters:
|
|
- meta_content_scope: meta.function.parameters.python
|
|
- match: \)
|
|
scope: punctuation.section.parameters.end.python
|
|
set: function-after-parameters
|
|
- include: comments
|
|
- match: ','
|
|
scope: punctuation.separator.parameters.python
|
|
push: allow-unpack-operators
|
|
- match: /
|
|
scope: storage.modifier.positional-args-only.python
|
|
push:
|
|
- match: (?=[,)])
|
|
pop: true
|
|
- match: \S
|
|
scope: invalid.illegal.expected-comma.python
|
|
- match: '(?==)'
|
|
set:
|
|
- match: '='
|
|
scope: keyword.operator.assignment.python
|
|
set:
|
|
- meta_scope: meta.function.parameters.default-value.python
|
|
- match: '(?=[,)])'
|
|
set: [function-parameters, allow-unpack-operators]
|
|
- include: illegal-assignment-expression
|
|
- include: expression-in-a-group
|
|
- match: '(?=:)'
|
|
set:
|
|
- match: ':'
|
|
scope: punctuation.separator.annotation.parameter.python
|
|
set:
|
|
- meta_scope: meta.function.parameters.annotation.python
|
|
- match: '(?=[,)=])'
|
|
set: function-parameters
|
|
- include: illegal-assignment-expression
|
|
- include: expression-in-a-group
|
|
- include: function-parameters-tuple
|
|
- include: illegal-names
|
|
- match: '{{identifier}}'
|
|
scope: variable.parameter.python
|
|
- include: line-continuation
|
|
|
|
function-parameters-tuple:
|
|
# python 2 style tuple arguments
|
|
# removed from python 3 since PEP-3113
|
|
- match: \(
|
|
scope: punctuation.section.group.begin.python
|
|
push:
|
|
- meta_scope: meta.group.python
|
|
- match: \)
|
|
scope: punctuation.section.group.end.python
|
|
set: after-expression
|
|
- include: comments
|
|
- match: ','
|
|
scope: punctuation.separator.parameters.python
|
|
push: allow-unpack-operators
|
|
# default values should follow the argument
|
|
- match: '='
|
|
push:
|
|
- meta_scope: invalid.illegal.default-value.python
|
|
- match: '(?=[,)=])'
|
|
pop: true
|
|
# python 2 does not support type annotations
|
|
- match: '(?=:)'
|
|
push:
|
|
- meta_scope: invalid.illegal.annotation.python
|
|
- match: '(?=[,)=])'
|
|
pop: true
|
|
- include: illegal-names
|
|
- match: '{{identifier}}'
|
|
scope: variable.parameter.python
|
|
- include: line-continuation
|
|
|
|
function-after-parameters:
|
|
- meta_content_scope: meta.function.python
|
|
- match: (?=->)
|
|
set: [function-return-type, function-return-type-separator]
|
|
- include: function-terminator
|
|
|
|
function-return-type:
|
|
- meta_content_scope: meta.function.annotation.return.python
|
|
- include: illegal-assignment-expression
|
|
- include: function-terminator
|
|
- include: expression-in-a-statement
|
|
|
|
function-return-type-separator:
|
|
- match: ->
|
|
scope: punctuation.separator.annotation.return.python
|
|
pop: true
|
|
|
|
function-terminator:
|
|
- match: ':'
|
|
scope: meta.function.python punctuation.section.function.begin.python
|
|
pop: true
|
|
- include: line-continuation-or-pop
|
|
|
|
decorators:
|
|
- match: ^\s*(?=@)
|
|
push:
|
|
# Due to line continuations, we don't know whether this is a "function call" yet
|
|
- meta_content_scope: meta.annotation.python
|
|
- match: '@'
|
|
scope: punctuation.definition.annotation.python
|
|
- match: $
|
|
pop: true
|
|
- include: line-continuation-or-pop
|
|
- match: (?=\.?\s*{{path}}\s*\() # now we do
|
|
set: [after-expression, decorator-function-call-wrapper, qualified-name-until-leaf]
|
|
- match: (?=\.?\s*{{path}})
|
|
push: [decorator-wrapper, qualified-name-until-leaf]
|
|
- match: \S
|
|
scope: invalid.illegal.character.python
|
|
pop: true
|
|
|
|
decorator-wrapper:
|
|
- match: (\.)\s*
|
|
captures:
|
|
1: punctuation.accessor.dot.python
|
|
set:
|
|
- meta_scope: meta.qualified-name.python
|
|
- meta_content_scope: variable.annotation.python
|
|
- include: dotted-name-specials
|
|
- include: generic-names
|
|
- match: ''
|
|
pop: true
|
|
- match: ''
|
|
set:
|
|
- meta_scope: meta.qualified-name.python variable.annotation.python
|
|
- include: name-specials
|
|
- include: generic-names
|
|
- match: ''
|
|
pop: true
|
|
|
|
decorator-function-call-wrapper:
|
|
- meta_scope: meta.annotation.function.python
|
|
- match: \)
|
|
scope: punctuation.section.arguments.end.python
|
|
pop: true
|
|
- match: \(
|
|
scope: meta.annotation.function.python punctuation.section.arguments.begin.python
|
|
push: [decorator-function-call-arguments, allow-unpack-operators]
|
|
- match: (\.)\s*
|
|
captures:
|
|
1: punctuation.accessor.dot.python
|
|
push:
|
|
- meta_scope: meta.qualified-name.python
|
|
- meta_content_scope: variable.annotation.function.python
|
|
- include: dotted-name-specials
|
|
- include: generic-names
|
|
- match: ''
|
|
pop: true
|
|
- match: ''
|
|
push:
|
|
- meta_scope: meta.qualified-name.python variable.annotation.function.python
|
|
- include: name-specials
|
|
- include: generic-names
|
|
- match: ''
|
|
pop: true
|
|
|
|
decorator-function-call-arguments:
|
|
- clear_scopes: 1
|
|
- meta_content_scope: meta.annotation.arguments.python
|
|
- match: (?=\))
|
|
pop: true
|
|
- include: arguments
|
|
|
|
item-access:
|
|
- match: '(?={{path}}\s*\[)'
|
|
push:
|
|
- match: \]
|
|
scope: meta.item-access.python punctuation.section.brackets.end.python
|
|
set: after-expression
|
|
- match: '(?={{path}}\s*\[)'
|
|
push:
|
|
- meta_content_scope: meta.item-access.python
|
|
- match: '(?=\s*\[)'
|
|
pop: true
|
|
- include: qualified-name
|
|
- match: \[
|
|
scope: meta.item-access.python punctuation.section.brackets.begin.python
|
|
push:
|
|
- meta_content_scope: meta.item-access.arguments.python
|
|
- match: '(?=\])'
|
|
pop: true
|
|
- match: ':'
|
|
scope: punctuation.separator.slice.python
|
|
- include: expression-in-a-group
|
|
|
|
function-calls:
|
|
- match: '(?=(\.\s*)?{{path}}\s*\()'
|
|
push: [function-call-wrapper, qualified-name-until-leaf]
|
|
|
|
function-call-wrapper:
|
|
- meta_scope: meta.function-call.python
|
|
- match: (?=\() # need to remove meta.function-call.python from opening parens
|
|
set:
|
|
- match: \(
|
|
scope: punctuation.section.arguments.begin.python
|
|
set: [after-expression, function-call-arguments, allow-unpack-operators]
|
|
- match: (\.)\s*(?={{identifier}})
|
|
captures:
|
|
1: punctuation.accessor.dot.python
|
|
push:
|
|
- meta_scope: meta.qualified-name.python
|
|
- meta_content_scope: variable.function.python
|
|
- include: dotted-name-specials
|
|
- include: generic-names
|
|
- match: ''
|
|
pop: true
|
|
- match: (?={{identifier}})
|
|
push:
|
|
- meta_scope: meta.qualified-name.python variable.function.python
|
|
- include: name-specials
|
|
- include: generic-names
|
|
- match: ''
|
|
pop: true
|
|
|
|
function-call-arguments:
|
|
- meta_scope: meta.function-call.arguments.python
|
|
- match: \)
|
|
scope: punctuation.section.arguments.end.python
|
|
pop: true
|
|
- include: arguments
|
|
|
|
arguments:
|
|
- include: keyword-arguments
|
|
- match: ','
|
|
scope: punctuation.separator.arguments.python
|
|
push: allow-unpack-operators
|
|
- include: inline-for
|
|
- include: expression-in-a-group
|
|
|
|
keyword-arguments:
|
|
- match: '(?={{identifier}}\s*=(?!=))'
|
|
push:
|
|
- include: line-continuation-or-pop
|
|
- match: '='
|
|
scope: keyword.operator.assignment.python
|
|
set:
|
|
- include: illegal-assignment-expression
|
|
- match: (?=[,):])
|
|
pop: true
|
|
- include: expression-in-a-group
|
|
- include: illegal-names
|
|
- match: '{{identifier}}'
|
|
scope: variable.parameter.python
|
|
|
|
lambda:
|
|
- match: \b(lambda)(?=\s|:|$)
|
|
scope:
|
|
meta.function.inline.python
|
|
storage.type.function.inline.python
|
|
keyword.declaration.function.inline.python
|
|
push: [lambda-parameters, allow-unpack-operators]
|
|
|
|
lambda-parameters:
|
|
- meta_content_scope: meta.function.inline.parameters.python
|
|
- include: line-continuation-or-pop
|
|
- match: '\:'
|
|
scope: punctuation.section.function.begin.python
|
|
set:
|
|
# clear meta_scope
|
|
- match: ''
|
|
set:
|
|
- meta_scope: meta.function.inline.body.python
|
|
- include: illegal-assignment-expression
|
|
# We don't know whether we are within a grouped
|
|
# or line-statement context at this point.
|
|
# If we're in a group, the underlying context will take over
|
|
# at the end of the line.
|
|
- match: (?=[,:)}\]])|$
|
|
pop: true
|
|
- include: expression-in-a-statement
|
|
- match: ','
|
|
scope: punctuation.separator.parameters.python
|
|
push: allow-unpack-operators
|
|
- include: keyword-arguments
|
|
- include: function-parameters-tuple
|
|
- include: illegal-names
|
|
- match: '{{identifier}}'
|
|
scope: variable.parameter.python
|
|
- match: '\S'
|
|
scope: invalid.illegal.expected-parameter.python
|
|
|
|
groups:
|
|
- match: \(
|
|
scope: punctuation.section.group.begin.python
|
|
push:
|
|
- meta_scope: meta.group.python
|
|
- match: \)
|
|
scope: punctuation.section.group.end.python
|
|
set: after-expression
|
|
- match: ','
|
|
scope: punctuation.separator.tuple.python
|
|
- include: inline-for
|
|
- include: expression-in-a-group
|
|
|
|
tuples:
|
|
# We don't know for certain, whether a parenthesized expression is a tuple,
|
|
# so try looking ahead.
|
|
- match: (\()\s*(\))
|
|
scope: meta.sequence.tuple.empty.python
|
|
captures:
|
|
1: punctuation.section.sequence.begin.python
|
|
2: punctuation.section.sequence.end.python
|
|
push: after-expression
|
|
- match: \((?={{simple_expression}},|\s*\*{{path}})
|
|
scope: punctuation.section.sequence.begin.python
|
|
push: inside-tuple
|
|
# TODO generator
|
|
# - match: \((?:{{simple_expression}}for)
|
|
|
|
inside-tuple:
|
|
- meta_scope: meta.sequence.tuple.python
|
|
- match: \)
|
|
scope: punctuation.section.sequence.end.python
|
|
set: after-expression
|
|
- match: ','
|
|
scope: punctuation.separator.sequence.python
|
|
push: allow-unpack-operators
|
|
- include: inline-for
|
|
- include: expression-in-a-group
|
|
|
|
lists:
|
|
- match: (\[)\s*(\])
|
|
scope: meta.sequence.list.empty.python
|
|
captures:
|
|
1: punctuation.section.sequence.begin.python
|
|
2: punctuation.section.sequence.end.python
|
|
push: after-expression
|
|
- match: \[
|
|
scope: punctuation.section.sequence.begin.python
|
|
push: [inside-list, allow-unpack-operators]
|
|
|
|
inside-list:
|
|
- meta_scope: meta.sequence.list.python
|
|
- match: \]
|
|
scope: punctuation.section.sequence.end.python
|
|
set: after-expression
|
|
- match: ','
|
|
scope: punctuation.separator.sequence.python
|
|
push: allow-unpack-operators
|
|
- include: inline-for
|
|
- include: expression-in-a-group
|
|
|
|
dictionaries-and-sets:
|
|
# Dictionaries and set literals use the same punctuation,
|
|
# so we try looking ahead to determine whether we have a dict or a set.
|
|
- match: '(\{)\s*(\})'
|
|
scope: meta.mapping.empty.python
|
|
captures:
|
|
1: punctuation.section.mapping.begin.python
|
|
2: punctuation.section.mapping.end.python
|
|
push: after-expression
|
|
- match: \{(?={{simple_expression}}:|\s*\*\*)
|
|
scope: punctuation.section.mapping.begin.python
|
|
push: inside-dictionary
|
|
- match: \{(?={{simple_expression}}[,}]|\s*\*)
|
|
scope: punctuation.section.set.begin.python
|
|
push: inside-set
|
|
# If the expression is "more complex" or on the next line,
|
|
# fall back to default and determine later.
|
|
- match: \{
|
|
scope: punctuation.section.mapping-or-set.begin.python
|
|
push:
|
|
- meta_scope: meta.mapping-or-set.python
|
|
- match: \}
|
|
scope: punctuation.section.mapping-or-set.end.python
|
|
set: after-expression
|
|
- match: (?={{simple_expression}}:|\s*\*\*)
|
|
set: inside-dictionary
|
|
- match: (?={{simple_expression}}[,}]|\s*\*)
|
|
set: inside-set
|
|
- match: ','
|
|
scope: punctuation.separator.set.python
|
|
set: inside-set
|
|
- include: illegal-assignment-expression
|
|
- match: ':'
|
|
scope: punctuation.separator.mapping.key-value.python
|
|
set: inside-directory-value
|
|
- include: inline-for
|
|
- include: expression-in-a-group
|
|
|
|
inside-dictionary:
|
|
- meta_scope: meta.mapping.python
|
|
- match: \}
|
|
scope: punctuation.section.mapping.end.python
|
|
set: after-expression
|
|
- include: illegal-assignment-expression
|
|
- match: ':'
|
|
scope: punctuation.separator.mapping.key-value.python
|
|
set: inside-directory-value
|
|
- match: \*\*
|
|
scope: keyword.operator.unpacking.mapping.python
|
|
push:
|
|
- match: (?=\})
|
|
pop: true
|
|
- match: ','
|
|
scope: punctuation.separator.mapping.python
|
|
pop: true
|
|
- include: expression-in-a-group
|
|
- include: comments
|
|
- match: (?=\S)
|
|
push:
|
|
- clear_scopes: 1
|
|
- meta_scope: meta.mapping.key.python
|
|
- match: \s*(?=\}|,|:)
|
|
pop: true
|
|
- include: expression-in-a-group
|
|
|
|
inside-directory-value:
|
|
- meta_content_scope: meta.mapping.python
|
|
- match: \}
|
|
scope: punctuation.section.mapping.end.python
|
|
set: after-expression
|
|
- match: (?=,)
|
|
set:
|
|
# clear meta scope from this match, because 'inside-directory' has it in meta_scope
|
|
- match: ','
|
|
scope: punctuation.separator.mapping.python
|
|
set: inside-dictionary
|
|
- match: (?=(?:async|for)\b)
|
|
push:
|
|
- match: (?=\})
|
|
pop: true
|
|
- match: ','
|
|
scope: invalid.illegal.unexpected-comma.python
|
|
- include: inline-for
|
|
- include: expression-in-a-group
|
|
- include: comments
|
|
- match: (?=\S)
|
|
push:
|
|
- clear_scopes: 1
|
|
- meta_content_scope: meta.mapping.value.python
|
|
- match: (?=\s*(\}|,|(?:async|for)\b))
|
|
pop: true
|
|
- include: expression-in-a-group
|
|
|
|
inside-set:
|
|
- meta_scope: meta.set.python
|
|
- match: \}
|
|
scope: punctuation.section.set.end.python
|
|
set: after-expression
|
|
- include: illegal-assignment-expression
|
|
- match: ':'
|
|
scope: invalid.illegal.colon-inside-set.python
|
|
- match: ','
|
|
scope: punctuation.separator.set.python
|
|
- match: \*
|
|
scope: keyword.operator.unpacking.sequence.python
|
|
push:
|
|
- match: (?=\})
|
|
pop: true
|
|
- match: ','
|
|
scope: punctuation.separator.set.python
|
|
pop: true
|
|
- include: expression-in-a-group
|
|
- include: inline-for
|
|
- include: expression-in-a-group
|
|
|
|
builtin-exceptions:
|
|
- match: |-
|
|
(?x)\b(
|
|
(?:
|
|
Arithmetic|Assertion|Attribute|BlockingIO|BrokenPipe|Buffer|ChildProcess|
|
|
Connection(?:Aborted|Refused|Reset)?|EOF|Environment|FileExists|
|
|
FileNotFound|FloatingPoint|Interrupted|IO|IsADirectoryError|
|
|
Import|Indentation|Index|Key|Lookup|Memory|Name|NotADirectory|
|
|
NotImplemented|OS|Overflow|Permission|ProcessLookup|Reference|
|
|
Runtime|Standard|Syntax|System|Tab|Timeout|Type|UnboundLocal|
|
|
Unicode(?:Encode|Decode|Translate)?|Value|VMS|Windows|ZeroDivision
|
|
)Error|
|
|
(?:(?:Pending)?Deprecation|Resource|Runtime|Syntax|User|Future|Import|Unicode|Bytes)?Warning|
|
|
(?:Base)?Exception|
|
|
SystemExit|StopIteration|NotImplemented|KeyboardInterrupt|GeneratorExit
|
|
)\b
|
|
scope: support.type.exception.python
|
|
|
|
builtin-functions:
|
|
- match: |-
|
|
(?x)\b(?:
|
|
__import__|all|abs|any|ascii|bin|callable|chr|classmethod|
|
|
compile|delattr|dir|divmod|enumerate|eval|filter|format|getattr|
|
|
globals|hasattr|hash|help|hex|id|input|isinstance|issubclass|iter|
|
|
len|locals|map|max|min|next|oct|open|ord|pow|property|range|
|
|
repr|reversed|round|setattr|sorted|staticmethod|
|
|
sum|super|type|vars|zip
|
|
# Python 2 functions
|
|
|apply|cmp|coerce|execfile|intern|raw_input|reduce|reload|unichr|xrange
|
|
# Python 3 functions
|
|
|breakpoint|exec
|
|
)\b
|
|
scope: support.function.builtin.python
|
|
|
|
builtin-types:
|
|
- match: |-
|
|
(?x)\b(?:
|
|
bool|bytearray|bytes|complex|dict|float|frozenset|int|
|
|
list|memoryview|object|set|slice|str|tuple
|
|
# Python 2 types
|
|
|basestring|long|unicode
|
|
# Python 2 types prone to conflicts
|
|
# |buffer|file
|
|
)\b
|
|
scope: support.type.python
|
|
|
|
name:
|
|
- match: '(?={{identifier}})'
|
|
push:
|
|
- include: name-specials
|
|
- match: '{{identifier_constant}}'
|
|
scope: variable.other.constant.python
|
|
- include: generic-names
|
|
- match: ''
|
|
pop: true
|
|
|
|
dotted-name:
|
|
- match: '\s*(\.)\s*(?={{identifier}})'
|
|
captures:
|
|
1: punctuation.accessor.dot.python
|
|
push:
|
|
- include: dotted-name-specials
|
|
- match: '{{identifier_constant}}'
|
|
scope: variable.other.constant.python
|
|
- include: generic-names
|
|
- match: ''
|
|
pop: true
|
|
|
|
qualified-name:
|
|
- match: '(?={{path}})'
|
|
push:
|
|
- meta_scope: meta.qualified-name.python
|
|
- include: name
|
|
- include: dotted-name
|
|
- match: ''
|
|
pop: true
|
|
- match: \.
|
|
scope: punctuation.accessor.dot.python
|
|
|
|
qualified-name-until-leaf:
|
|
# Push this together with another context to match a qualified name
|
|
# until the last non-special identifier (if any).
|
|
# This allows the leaf to be scoped individually.
|
|
- meta_scope: meta.qualified-name.python
|
|
# If a line continuation follows, this may or may not be the last leaf (most likley not though)
|
|
- match: (?={{identifier}}\s*(\.|\\))
|
|
push:
|
|
- include: name-specials
|
|
- include: generic-names
|
|
- match: ''
|
|
pop: true
|
|
- match: (\.)\s*(?={{identifier}}\s*(\.|\\))
|
|
captures:
|
|
1: punctuation.accessor.dot.python
|
|
push:
|
|
- include: dotted-name-specials
|
|
- include: generic-names
|
|
- match: ''
|
|
pop: true
|
|
- match: \.(?!\s*{{identifier}}) # don't match last dot
|
|
scope: punctuation.accessor.dot.python
|
|
- match: (?=\S|$)
|
|
pop: true
|
|
|
|
name-specials:
|
|
- include: builtin-functions
|
|
- include: builtin-types
|
|
- include: builtin-exceptions
|
|
- include: illegal-names
|
|
- include: magic-function-names
|
|
- include: magic-variable-names
|
|
- include: language-variables
|
|
|
|
dotted-name-specials:
|
|
- include: magic-function-names
|
|
- include: magic-variable-names
|
|
- include: illegal-names
|
|
|
|
entity-name-class:
|
|
- include: illegal-names
|
|
- include: generic-names
|
|
|
|
entity-name-function:
|
|
- include: magic-function-names
|
|
- include: illegal-names
|
|
- include: generic-names
|
|
|
|
generic-names:
|
|
- match: '{{identifier}}'
|
|
scope: meta.generic-name.python
|
|
|
|
illegal-names:
|
|
- match: \b{{illegal_names}}\b
|
|
scope: invalid.illegal.name.python
|
|
|
|
illegal-names-pop:
|
|
- match: \b{{illegal_names}}\b
|
|
scope: invalid.illegal.name.python
|
|
pop: true
|
|
|
|
language-variables:
|
|
- match: \b(self|cls)\b
|
|
scope: variable.language.python
|
|
- match: _(?!{{identifier_continue}})
|
|
scope: variable.language.python
|
|
|
|
line-continuation:
|
|
- match: (\\)(.*)$\n?
|
|
captures:
|
|
1: punctuation.separator.continuation.line.python
|
|
2: invalid.illegal.unexpected-text.python
|
|
# make sure to resume parsing at next line
|
|
push:
|
|
# This prevents strings after a continuation from being a docstring
|
|
- include: strings
|
|
- match: (?=\S|^\s*$|\n) # '\n' for when we matched a string earlier
|
|
pop: true
|
|
|
|
line-continuation-or-pop:
|
|
- include: line-continuation
|
|
- match: (?=\s*($|;|#))
|
|
pop: true
|
|
|
|
magic-function-names:
|
|
# https://docs.python.org/2/reference/datamodel.html
|
|
# https://docs.python.org/3/reference/datamodel.html
|
|
- match: |-
|
|
(?x)\b__(?:
|
|
# unary operators
|
|
invert|neg|pos|abs|
|
|
# binary operators
|
|
add|and|div|divmod|floordiv|lshift|mod|mul|or|pow|rshift|sub|truediv|xor|
|
|
contains|
|
|
# right-hand binary operators
|
|
radd|rand|rdiv|rdivmod|rfloordiv|rlshift|rmod|rmul|ror|rpow|rrshift|rsub|rtruediv|rxor|
|
|
# in-place operator assignments
|
|
iadd|iand|idiv|ifloordiv|ilshift|imod|imul|ior|ipow|irshift|isub|itruediv|ixor|
|
|
# comparisons
|
|
eq|ge|gt|le|lt|ne|
|
|
cmp|rcmp| # py2
|
|
# primary coercion
|
|
bool|str|
|
|
nonzero|unicode| # py2
|
|
# number coercion (converts something to a number)
|
|
bytes|complex|float|index|int|round|
|
|
long| # py2
|
|
# other "coercion"
|
|
format|len|length_hint|hash|repr|reversed|
|
|
coerce|hex|oct| # py2
|
|
fspath|
|
|
# iterator (and 'await')
|
|
iter|next|
|
|
aiter|anext|
|
|
await|
|
|
# attribute and item access
|
|
delattr|delitem|delslice|
|
|
getattr|getattribute|getitem|getslice|
|
|
setattr|setitem|setslice|
|
|
dir|missing|
|
|
# context manager
|
|
enter|exit|
|
|
aenter|aexit|
|
|
# other class magic
|
|
call|del|init|new|init_subclass|
|
|
instancecheck|subclasscheck|
|
|
# pickling
|
|
getnewargs|getnewargs_ex|getstate|setstate|reduce|reduce_ex|
|
|
# descriptors
|
|
delete|get|set|set_name|
|
|
# class-specific
|
|
subclasses|
|
|
# dataclasses (PEP 557)
|
|
post_init|
|
|
# for typing core support (PEP 560)
|
|
class_getitem|mro_entries
|
|
)__\b
|
|
comment: these methods have magic interpretation by python and are generally called indirectly through syntactic constructs
|
|
scope: support.function.magic.python
|
|
|
|
magic-variable-names:
|
|
# magic variables which a class/module/object may have.
|
|
# https://docs.python.org/3/library/inspect.html#types-and-members
|
|
# https://docs.python.org/3/reference/datamodel.html#object.__slots__
|
|
# https://docs.python.org/3/reference/datamodel.html#preparing-the-class-namespace
|
|
- match: |-
|
|
(?x)\b__(?:
|
|
# generic object
|
|
class|dict|doc|module|name|
|
|
# module-specific / global
|
|
all|file|package|
|
|
# functions & methods
|
|
annotations|closure|code|defaults|func|globals|kwdefaults|self|qualname|
|
|
# classes (attributes)
|
|
bases|prepare|slots|metaclass|mro|
|
|
# Python 2
|
|
members|methods
|
|
)__\b
|
|
scope: support.variable.magic.python
|
|
|
|
docstrings:
|
|
- match: ^\s*(?=(?i)(ur|ru|u|r)?("""|'''))
|
|
push:
|
|
- match: (?i)(u)?("""|''')
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: punctuation.definition.comment.begin.python
|
|
set:
|
|
- meta_scope: comment.block.documentation.python
|
|
- include: escaped-unicode-char
|
|
- include: escaped-char
|
|
- match: '\2'
|
|
scope: punctuation.definition.comment.end.python
|
|
pop: true
|
|
- match: (?i)(u?ru?)("""|''')
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: punctuation.definition.comment.begin.python
|
|
set:
|
|
- meta_scope: comment.block.documentation.python
|
|
- match: '\2'
|
|
scope: punctuation.definition.comment.end.python
|
|
pop: true
|
|
|
|
escaped-char:
|
|
- match: '(\\x\h{2})|(\\[0-7]{1,3})|(\\[\\"''abfnrtv])'
|
|
captures:
|
|
1: constant.character.escape.hex.python
|
|
2: constant.character.escape.octal.python
|
|
3: constant.character.escape.python
|
|
- match: \\. # deprecated in 3.6 and will eventually be a syntax error
|
|
scope: invalid.deprecated.character.escape.python
|
|
|
|
escaped-unicode-char:
|
|
- match: '(\\U\h{8})|(\\u\h{4})|(\\N\{[-a-zA-Z ]+\})'
|
|
captures:
|
|
1: constant.character.escape.unicode.16-bit-hex.python
|
|
2: constant.character.escape.unicode.32-bit-hex.python
|
|
3: constant.character.escape.unicode.name.python
|
|
|
|
escaped-fstring-escape:
|
|
# special-case the '\{{' sequence because it has higher priority than the deprecated '\{'
|
|
- match: (\\)(\{\{|\}\})
|
|
scope: constant.character.escape.backslash.regexp
|
|
captures:
|
|
1: invalid.deprecated.character.escape.python
|
|
2: constant.character.escape.python
|
|
|
|
line-continuation-inside-string:
|
|
- match: (\\)$\n?
|
|
captures:
|
|
1: punctuation.separator.continuation.line.python
|
|
- match: \n
|
|
scope: invalid.illegal.unclosed-string.python
|
|
set: after-expression
|
|
|
|
line-continuation-inside-block-string:
|
|
- match: \\$
|
|
scope: punctuation.separator.continuation.line.python
|
|
|
|
constant-placeholder:
|
|
- match: |- # printf style
|
|
(?x)
|
|
%
|
|
( \( ({{identifier}}) \) )? # mapping key
|
|
\#? # alternate form
|
|
0? # pad with zeros
|
|
\-? # left-adjust
|
|
\ ? # implicit sign
|
|
[+-]? # sign
|
|
(\d*|\*) # width
|
|
(\. (\d*|\*))? # precision
|
|
[hlL]? # length modifier (but ignored)
|
|
[acdeEfFgGiorsuxX%]
|
|
scope: constant.other.placeholder.python
|
|
captures:
|
|
2: variable.other.placeholder.python
|
|
- match: '{{strftime_spec}}'
|
|
scope: constant.other.placeholder.python
|
|
- match: '\{\{|\}\}'
|
|
scope: constant.character.escape.python
|
|
- include: formatting-syntax
|
|
|
|
formatting-syntax:
|
|
# https://docs.python.org/3.6/library/string.html#formatstrings
|
|
# Technically allows almost every character for the key,
|
|
# but those are rarely used if ever.
|
|
- match: |- # simple form
|
|
(?x)
|
|
(\{)
|
|
(?: [\w.\[\]]+)? # field_name
|
|
( ! [ars])? # conversion
|
|
(?: (:) ({{format_spec}}| # format_spec OR
|
|
[^}%]*%.[^}]*) # any format-like string
|
|
)?
|
|
(\})
|
|
scope: constant.other.placeholder.python
|
|
captures:
|
|
1: punctuation.definition.placeholder.begin.python
|
|
2: storage.modifier.conversion.python
|
|
3: punctuation.separator.format-spec.python
|
|
4: meta.format-spec.python constant.other.format-spec.python
|
|
5: punctuation.definition.placeholder.end.python
|
|
- match: (?=\{[^{}"']+\{[^"']*\}) # complex (nested) form
|
|
branch_point: formatting-syntax-branch
|
|
branch:
|
|
- formatting-syntax-complex
|
|
- formatting-syntax-fallback
|
|
|
|
formatting-syntax-fallback:
|
|
- match: \{
|
|
scope: meta.debug.formatting-syntax-fallback.python
|
|
pop: true
|
|
|
|
formatting-syntax-complex:
|
|
- match: \{
|
|
scope: punctuation.definition.placeholder.begin.python
|
|
set:
|
|
- meta_scope: constant.other.placeholder.python
|
|
- match: \}
|
|
scope: punctuation.definition.placeholder.end.python
|
|
pop: true
|
|
# TODO could match numeric indices or everything else as a key
|
|
# and also [] indexing
|
|
- match: '![ars]'
|
|
scope: storage.modifier.conversion.python
|
|
- match: ':'
|
|
scope: punctuation.separator.format-spec.python
|
|
push:
|
|
- meta_content_scope: meta.format-spec.python constant.other.format-spec.python
|
|
- match: (?=\})
|
|
pop: true
|
|
- match: (?=\{)
|
|
push: formatting-syntax-complex
|
|
- match: '[{"''\n]'
|
|
fail: formatting-syntax-branch
|
|
|
|
f-string-content:
|
|
# https://www.python.org/dev/peps/pep-0498/
|
|
# https://docs.python.org/3.6/reference/lexical_analysis.html#f-strings
|
|
- match: \{\{|\}\}
|
|
scope: constant.character.escape.python
|
|
- match: \{\s*\}
|
|
scope: invalid.illegal.empty-expression.python
|
|
- match: (?=\{)
|
|
push: f-string-replacement
|
|
- match: \}
|
|
scope: invalid.illegal.stray-brace.python
|
|
|
|
f-string-content-with-regex:
|
|
# Same as f-string-content, but will reset the entire scope stack
|
|
# and has an additional match.
|
|
- match: \\(\{\{|\}\})
|
|
scope: constant.character.escape.backslash.regexp
|
|
captures:
|
|
1: constant.character.escape.python
|
|
- match: \{\{|\}\}
|
|
scope: constant.character.escape.python
|
|
- match: \{\s*\}
|
|
scope: invalid.illegal.empty-expression.python
|
|
- match: (?=\{)
|
|
push: f-string-replacement-reset
|
|
- match: \}
|
|
scope: invalid.illegal.stray-brace.python
|
|
|
|
f-string-replacement:
|
|
- clear_scopes: 1
|
|
- match: \}
|
|
scope: meta.interpolation.python punctuation.section.interpolation.end.python
|
|
pop: true
|
|
- match: \{
|
|
scope: punctuation.section.interpolation.begin.python
|
|
push:
|
|
- meta_scope: meta.interpolation.python
|
|
- match: (?=\})
|
|
pop: true
|
|
- match: '![ars]'
|
|
scope: storage.modifier.conversion.python
|
|
- match: =
|
|
scope: storage.modifier.debug.python
|
|
- match: ':'
|
|
push:
|
|
- meta_scope: meta.format-spec.python constant.other.format-spec.python
|
|
# Because replacements can also be used *within* the format-spec,
|
|
# basically any character is valid and matching {{format_spec}} is useless.
|
|
# - match: '{{format_spec}}'
|
|
- match: (?=\})
|
|
pop: true
|
|
- include: f-string-content
|
|
- match: ''
|
|
push:
|
|
- meta_content_scope: source.python.embedded
|
|
- match: (?==?(![^=]|:|\}))
|
|
pop: true
|
|
- match: \\
|
|
scope: invalid.illegal.backslash-in-fstring.python
|
|
- include: inline-for
|
|
- include: expression-in-a-group
|
|
|
|
f-string-replacement-reset:
|
|
# Same as f-string-replacement, but with clear_scopes: true
|
|
- clear_scopes: true
|
|
- meta_scope: source.python meta.string.interpolated.python
|
|
- match: \}
|
|
scope: meta.interpolation.python punctuation.section.interpolation.end.python
|
|
pop: true
|
|
- match: \{
|
|
scope: punctuation.section.interpolation.begin.python
|
|
push:
|
|
- meta_scope: meta.interpolation.python
|
|
- match: (?=\})
|
|
pop: true
|
|
- match: '![ars]'
|
|
scope: storage.modifier.conversion.python
|
|
- match: ':'
|
|
push:
|
|
- meta_scope: meta.format-spec.python constant.other.format-spec.python
|
|
- match: (?=\})
|
|
pop: true
|
|
- include: f-string-content
|
|
- match: ''
|
|
push:
|
|
- meta_content_scope: source.python.embedded
|
|
- match: (?=![^=]|:|\})
|
|
pop: true
|
|
- match: \\
|
|
scope: invalid.illegal.backslash-in-fstring.python
|
|
- include: inline-for
|
|
- include: expression-in-a-group
|
|
|
|
string-quoted-double-block:
|
|
# Triple-quoted capital R raw string, unicode or not, no syntax embedding
|
|
- match: '([uU]?R)(""")'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.double.block.python
|
|
- match: '"""'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: escaped-unicode-char
|
|
# Triple-quoted capital R raw string, bytes, no syntax embedding
|
|
- match: '([bB]R|R[bB])(""")'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.double.block.python
|
|
- match: '"""'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
# Triple-quoted raw string, unicode or not, will detect SQL, otherwise regex
|
|
- match: '([uU]?r)(""")'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.double.block.python
|
|
- match: '(?={{sql_indicator}})'
|
|
set:
|
|
- meta_scope: meta.string.python string.quoted.double.block.python
|
|
- match: '"""'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- match: ''
|
|
push: scope:source.sql
|
|
with_prototype:
|
|
- match: '(?=""")'
|
|
pop: true
|
|
- include: escaped-unicode-char
|
|
- include: constant-placeholder
|
|
- match: '(?=\S)'
|
|
set:
|
|
- meta_scope: meta.string.python string.quoted.double.block.python
|
|
- match: '"""'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- match: ''
|
|
push: scope:source.regexp.python
|
|
with_prototype:
|
|
- match: '(?=""")'
|
|
pop: true
|
|
- include: escaped-unicode-char
|
|
# Triple-quoted raw string, bytes, will use regex
|
|
- match: '([bB]r|r[bB])(""")'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.double.block.python
|
|
- match: '"""'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- match: ''
|
|
embed: scope:source.regexp.python
|
|
escape: (?=""")
|
|
# Triple-quoted raw f-string
|
|
- match: ([fF]R|R[fF])(""")
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.interpolated.python string.quoted.double.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.interpolated.python string.quoted.double.block.python
|
|
- match: '"""'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: f-string-content
|
|
# Triple-quoted raw f-string, treated as regex
|
|
- match: ([fF]r|r[fF])(""")
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.interpolated.python string.quoted.double.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.interpolated.python string.quoted.double.block.python
|
|
- match: '"""'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- match: ''
|
|
push: scope:source.regexp.python
|
|
with_prototype:
|
|
- match: '(?=""")'
|
|
pop: true
|
|
- include: f-string-content-with-regex
|
|
# Triple-quoted f-string
|
|
- match: ([fF])(""")
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.interpolated.python string.quoted.double.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.interpolated.python string.quoted.double.block.python
|
|
- match: '"""'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-block-string
|
|
- include: escaped-fstring-escape
|
|
- include: escaped-unicode-char
|
|
- include: escaped-char
|
|
- include: f-string-content
|
|
# Triple-quoted string, unicode or not, will detect SQL
|
|
- match: '([uU]?)(""")'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.double.block.python
|
|
- match: '(?={{sql_indicator}})'
|
|
set:
|
|
- meta_scope: meta.string.python string.quoted.double.block.python
|
|
- match: '"""'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- match: ''
|
|
push: scope:source.sql
|
|
with_prototype:
|
|
- match: '(?=""")'
|
|
pop: true
|
|
- include: line-continuation-inside-block-string
|
|
- include: escaped-unicode-char
|
|
- include: escaped-char
|
|
- include: constant-placeholder
|
|
- match: '(?=\S)'
|
|
set:
|
|
- meta_scope: meta.string.python string.quoted.double.block.python
|
|
- match: '"""'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-block-string
|
|
- include: escaped-unicode-char
|
|
- include: escaped-char
|
|
- include: constant-placeholder
|
|
# Triple-quoted string, bytes, no syntax embedding
|
|
- match: '([bB])(""")'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.double.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.double.block.python
|
|
- match: '"""'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-block-string
|
|
- include: escaped-char
|
|
- include: constant-placeholder
|
|
|
|
string-quoted-double:
|
|
# Single-line capital R raw string, unicode or not, no syntax embedding
|
|
- match: '([uU]?R)(")'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.double.python
|
|
- match: '"'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-string
|
|
# Single-line capital R raw string, bytes, no syntax embedding
|
|
- match: '([bB]R|R[bB])(")'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.double.python
|
|
- match: '"'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-string
|
|
# Single-line raw string, unicode or not, starting with a SQL keyword
|
|
- match: '([uU]?r)(")(?={{sql_indicator}})'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.double.python
|
|
- match: '"'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-string
|
|
- match: ''
|
|
push: scope:source.sql
|
|
with_prototype:
|
|
- match: '(?="|\n)'
|
|
pop: true
|
|
- include: constant-placeholder
|
|
- include: line-continuation-inside-string
|
|
# Single-line raw string, unicode or not, treated as regex
|
|
- match: '([uU]?r)(")'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.double.python
|
|
- match: '"'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-string
|
|
- match: ''
|
|
push: scope:source.regexp.python
|
|
with_prototype:
|
|
- match: '(?="|\n)'
|
|
pop: true
|
|
- include: line-continuation-inside-string
|
|
# Single-line raw string, bytes, treated as regex
|
|
- match: '([bB]r|r[bB])(")'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.double.python
|
|
- match: '"'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-string
|
|
- match: ''
|
|
embed: scope:source.regexp.python
|
|
escape: (?="|\n)
|
|
# Single-line raw f-string
|
|
- match: (R[fF]|[fF]R)(")
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.interpolated.python string.quoted.double.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.interpolated.python string.quoted.double.python
|
|
- match: '"'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-string
|
|
- include: f-string-content
|
|
# Single-line raw f-string, treated as regex
|
|
- match: (r[fF]|[fF]r)(")
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.interpolated.python string.quoted.double.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.interpolated.python string.quoted.double.python
|
|
- match: '"'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-string
|
|
- match: ''
|
|
push: scope:source.regexp.python
|
|
with_prototype:
|
|
- match: '(?="|\n)'
|
|
pop: true
|
|
- include: line-continuation-inside-string
|
|
- include: f-string-content-with-regex
|
|
# Single-line f-string
|
|
- match: ([fF])(")
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.interpolated.python string.quoted.double.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.interpolated.python string.quoted.double.python
|
|
- match: '"'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: escaped-fstring-escape
|
|
- include: escaped-unicode-char
|
|
- include: escaped-char
|
|
- include: line-continuation-inside-string
|
|
- include: f-string-content
|
|
# Single-line string, unicode or not, starting with a SQL keyword
|
|
- match: '([uU]?)(")(?={{sql_indicator}})'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.double.python
|
|
- match: '"'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-string
|
|
- match: ''
|
|
push: scope:source.sql
|
|
with_prototype:
|
|
- match: '(?="|\n)'
|
|
pop: true
|
|
- include: escaped-unicode-char
|
|
- include: escaped-char
|
|
- include: line-continuation-inside-string
|
|
- include: constant-placeholder
|
|
# Single-line string, unicode or not
|
|
- match: '([uU]?)(")'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.double.python
|
|
- match: '"'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: escaped-unicode-char
|
|
- include: escaped-char
|
|
- include: line-continuation-inside-string
|
|
- include: constant-placeholder
|
|
# Single-line string, bytes
|
|
- match: '([bB])(")'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.double.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.double.python
|
|
- match: '"'
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: escaped-char
|
|
- include: line-continuation-inside-string
|
|
- include: constant-placeholder
|
|
|
|
string-quoted-single-block:
|
|
# Triple-quoted capital R raw string, unicode or not, no syntax embedding
|
|
- match: ([uU]?R)(''')
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.single.block.python
|
|
- match: "'''"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
# Triple-quoted capital R raw string, bytes, no syntax embedding
|
|
- match: ([bB]R|R[bB])(''')
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.single.block.python
|
|
- match: "'''"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
# Triple-quoted raw string, unicode or not, will detect SQL, otherwise regex
|
|
- match: ([uU]?r)(''')
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.single.block.python
|
|
- match: '(?={{sql_indicator}})'
|
|
set:
|
|
- meta_scope: meta.string.python string.quoted.single.block.python
|
|
- match: "'''"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- match: ''
|
|
push: scope:source.sql
|
|
with_prototype:
|
|
- match: (?=''')
|
|
pop: true
|
|
- include: escaped-unicode-char
|
|
- include: escaped-char
|
|
- include: constant-placeholder
|
|
- match: '(?=\S)'
|
|
set:
|
|
- meta_scope: meta.string.python string.quoted.single.block.python
|
|
- match: "'''"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- match: ''
|
|
push: scope:source.regexp.python
|
|
with_prototype:
|
|
- match: (?=''')
|
|
pop: true
|
|
- include: escaped-unicode-char
|
|
# Triple-quoted raw string, bytes, will use regex
|
|
- match: ([bB]r|r[bB])(''')
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.single.block.python
|
|
- match: "'''"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- match: ''
|
|
embed: scope:source.regexp.python
|
|
escape: (?=''')
|
|
# Triple-quoted raw f-string
|
|
- match: ([fF]R|R[fF])(''')
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.interpolated.python string.quoted.single.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.interpolated.python string.quoted.single.block.python
|
|
- match: "'''"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: f-string-content
|
|
# Triple-quoted raw f-string, treated as regex
|
|
- match: ([fF]r|r[fF])(''')
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.interpolated.python string.quoted.single.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.interpolated.python string.quoted.single.block.python
|
|
- match: "'''"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- match: ''
|
|
push: scope:source.regexp.python
|
|
with_prototype:
|
|
- match: (?=''')
|
|
pop: true
|
|
- include: f-string-content-with-regex
|
|
# Triple-quoted f-string
|
|
- match: ([fF])(''')
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.interpolated.python string.quoted.single.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.interpolated.python string.quoted.single.block.python
|
|
- match: "'''"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-block-string
|
|
- include: escaped-fstring-escape
|
|
- include: escaped-unicode-char
|
|
- include: escaped-char
|
|
- include: f-string-content
|
|
# Triple-quoted string, unicode or not, will detect SQL
|
|
- match: ([uU]?)(''')
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.single.block.python
|
|
- match: '(?={{sql_indicator}})'
|
|
set:
|
|
- meta_scope: meta.string.python string.quoted.single.block.python
|
|
- match: "'''"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- match: ''
|
|
push: scope:source.sql
|
|
with_prototype:
|
|
- match: (?=''')
|
|
pop: true
|
|
- include: line-continuation-inside-block-string
|
|
- include: escaped-unicode-char
|
|
- include: escaped-char
|
|
- include: constant-placeholder
|
|
- match: '(?=\S)'
|
|
set:
|
|
- meta_scope: meta.string.python string.quoted.single.block.python
|
|
- match: "'''"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-block-string
|
|
- include: escaped-unicode-char
|
|
- include: escaped-char
|
|
- include: constant-placeholder
|
|
# Triple-quoted string, bytes, no syntax embedding
|
|
- match: ([bB])(''')
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.single.block.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.single.block.python
|
|
- match: "'''"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-block-string
|
|
- include: escaped-char
|
|
- include: constant-placeholder
|
|
|
|
string-quoted-single:
|
|
# Single-line capital R raw string, unicode or not, no syntax embedding
|
|
- match: '([uU]?R)('')'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.single.python
|
|
- match: "'"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-string
|
|
# Single-line capital R raw string, bytes, no syntax embedding
|
|
- match: '([bB]R|R[bB])('')'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.single.python
|
|
- match: "'"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-string
|
|
# Single-line raw string, unicode or not, starting with a SQL keyword
|
|
- match: '([uU]?r)('')(?={{sql_indicator}})'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.single.python
|
|
- match: "'"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-string
|
|
- match: ''
|
|
push: scope:source.sql
|
|
with_prototype:
|
|
- match: '(?=''|\n)'
|
|
pop: true
|
|
- include: line-continuation-inside-string
|
|
- include: constant-placeholder
|
|
# Single-line raw string, unicode or not, treated as regex
|
|
- match: '([uU]?r)('')'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.single.python
|
|
- match: "'"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-string
|
|
- match: ''
|
|
push: scope:source.regexp.python
|
|
with_prototype:
|
|
- match: '(?=''|\n)'
|
|
pop: true
|
|
- include: line-continuation-inside-string
|
|
# Single-line raw string, bytes, treated as regex
|
|
- match: '([bB]r|r[bB])('')'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.single.python
|
|
- match: "'"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-string
|
|
- match: ''
|
|
push: scope:source.regexp.python
|
|
with_prototype:
|
|
- match: '(?=''|\n)'
|
|
pop: true
|
|
- include: line-continuation-inside-string
|
|
# Single-line raw f-string
|
|
- match: ([fF]R|R[fF])(')
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.interpolated.python string.quoted.single.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.interpolated.python string.quoted.single.python
|
|
- match: "'"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-string
|
|
- include: f-string-content
|
|
# Single-line raw f-string, treated as regex
|
|
- match: ([fF]r|r[fF])(')
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.interpolated.python string.quoted.single.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.interpolated.python string.quoted.single.python
|
|
- match: "'"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-string
|
|
- match: ''
|
|
push: scope:source.regexp.python
|
|
with_prototype:
|
|
- match: (?='|\n)
|
|
pop: true
|
|
- include: line-continuation-inside-string
|
|
- include: f-string-content-with-regex
|
|
# Single-line f-string
|
|
- match: ([fF])(')
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.interpolated.python string.quoted.single.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.interpolated.python string.quoted.single.python
|
|
- match: "'"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: escaped-fstring-escape
|
|
- include: escaped-unicode-char
|
|
- include: escaped-char
|
|
- include: line-continuation-inside-string
|
|
- include: f-string-content
|
|
# Single-line string, unicode or not, starting with a SQL keyword
|
|
- match: '([uU]?)('')(?={{sql_indicator}})'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.single.python
|
|
- match: "'"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: line-continuation-inside-string
|
|
- match: ''
|
|
push: scope:source.sql
|
|
with_prototype:
|
|
- match: '(?=''|\n)'
|
|
pop: true
|
|
- include: escaped-unicode-char
|
|
- include: escaped-char
|
|
- include: line-continuation-inside-string
|
|
- include: constant-placeholder
|
|
# Single-line string, unicode or not
|
|
- match: '([uU]?)('')'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.single.python
|
|
- match: "'"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: escaped-unicode-char
|
|
- include: escaped-char
|
|
- include: line-continuation-inside-string
|
|
- include: constant-placeholder
|
|
# Single-line string, bytes
|
|
- match: '([bB])('')'
|
|
captures:
|
|
1: storage.type.string.python
|
|
2: meta.string.python string.quoted.single.python punctuation.definition.string.begin.python
|
|
push:
|
|
- meta_content_scope: meta.string.python string.quoted.single.python
|
|
- match: "'"
|
|
scope: punctuation.definition.string.end.python
|
|
set: after-expression
|
|
- include: escaped-char
|
|
- include: line-continuation-inside-string
|
|
- include: constant-placeholder
|
|
|
|
strings:
|
|
# block versions must be matched first
|
|
- include: string-quoted-double-block
|
|
- include: string-quoted-double
|
|
- include: string-quoted-single-block
|
|
- include: string-quoted-single
|
|
|
|
inline-for:
|
|
- match: \b(?:(async)\s+)?(for)\b
|
|
captures:
|
|
1: storage.modifier.async.python
|
|
2: keyword.control.loop.for.generator.python
|
|
push:
|
|
- include: comments
|
|
- meta_scope: meta.expression.generator.python
|
|
- match: \bin\b
|
|
scope: keyword.control.loop.for.in.python
|
|
pop: true
|
|
- match: '(?=[)\]}])'
|
|
scope: invalid.illegal.missing-in.python
|
|
pop: true
|
|
- include: illegal-names-pop
|
|
- include: target-list
|
|
|
|
inline-if:
|
|
- match: \bif\b
|
|
scope: keyword.control.conditional.if.python
|
|
- match: \belse\b
|
|
scope: keyword.control.conditional.else.python
|
|
|
|
target-list:
|
|
- match: ','
|
|
scope: punctuation.separator.target-list.python
|
|
- match: \(
|
|
scope: punctuation.section.target-list.begin.python
|
|
push:
|
|
- include: comments
|
|
- match: ','
|
|
scope: punctuation.separator.target-list.python
|
|
- match: \)
|
|
scope: punctuation.section.target-list.end.python
|
|
pop: true
|
|
- include: target-list
|
|
- include: name
|
|
- include: name
|