summaryrefslogtreecommitdiff
path: root/tests/snippets/python
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2021-01-20 10:57:30 +0100
committerGeorg Brandl <georg@python.org>2021-01-20 10:57:30 +0100
commitb40b0cca067c2e9c2f69c91abbd27e79ad243b42 (patch)
tree6f81b370c551ea06e89ff8333b5939df5625e757 /tests/snippets/python
parentdc9bf0c256dbd88c72349822d59b25f9d8225dc6 (diff)
downloadpygments-git-b40b0cca067c2e9c2f69c91abbd27e79ad243b42.tar.gz
Rename "tests/lexers" to "tests/snippets" and update the contribution
docs to point to both snippets and examplefiles.
Diffstat (limited to 'tests/snippets/python')
-rw-r--r--tests/snippets/python/test_fstring_01a.txt25
-rw-r--r--tests/snippets/python/test_fstring_01b.txt25
-rw-r--r--tests/snippets/python/test_fstring_02a.txt13
-rw-r--r--tests/snippets/python/test_fstring_02b.txt13
-rw-r--r--tests/snippets/python/test_fstring_03a.txt14
-rw-r--r--tests/snippets/python/test_fstring_03b.txt14
-rw-r--r--tests/snippets/python/test_fstring_04a.txt13
-rw-r--r--tests/snippets/python/test_fstring_04b.txt13
-rw-r--r--tests/snippets/python/test_fstring_05a.txt16
-rw-r--r--tests/snippets/python/test_fstring_05b.txt16
-rw-r--r--tests/snippets/python/test_fstring_06a.txt16
-rw-r--r--tests/snippets/python/test_fstring_06b.txt16
-rw-r--r--tests/snippets/python/test_fstring_07a.txt17
-rw-r--r--tests/snippets/python/test_fstring_07b.txt17
-rw-r--r--tests/snippets/python/test_fstring_08a.txt15
-rw-r--r--tests/snippets/python/test_fstring_08b.txt15
-rw-r--r--tests/snippets/python/test_fstring_09a.txt14
-rw-r--r--tests/snippets/python/test_fstring_09b.txt14
-rw-r--r--tests/snippets/python/test_fstring_10a.txt18
-rw-r--r--tests/snippets/python/test_fstring_10b.txt18
-rw-r--r--tests/snippets/python/test_fstring_11a.txt18
-rw-r--r--tests/snippets/python/test_fstring_11b.txt18
-rw-r--r--tests/snippets/python/test_fstring_12a.txt16
-rw-r--r--tests/snippets/python/test_fstring_12b.txt16
-rw-r--r--tests/snippets/python/test_fstring_13a.txt17
-rw-r--r--tests/snippets/python/test_fstring_13b.txt17
-rw-r--r--tests/snippets/python/test_fstring_14a.txt20
-rw-r--r--tests/snippets/python/test_fstring_14b.txt20
-rw-r--r--tests/snippets/python/test_fstring_15a.txt42
-rw-r--r--tests/snippets/python/test_fstring_15b.txt42
-rw-r--r--tests/snippets/python/test_fstring_16a.txt18
-rw-r--r--tests/snippets/python/test_fstring_16b.txt18
-rw-r--r--tests/snippets/python/test_fstring_17a.txt14
-rw-r--r--tests/snippets/python/test_fstring_17b.txt14
-rw-r--r--tests/snippets/python/test_fstring_18a.txt25
-rw-r--r--tests/snippets/python/test_fstring_18b.txt25
-rw-r--r--tests/snippets/python/test_fstring_19a.txt46
-rw-r--r--tests/snippets/python/test_fstring_19b.txt46
-rw-r--r--tests/snippets/python/test_fstring_20a.txt17
-rw-r--r--tests/snippets/python/test_fstring_20b.txt17
-rw-r--r--tests/snippets/python/test_fstring_21a.txt15
-rw-r--r--tests/snippets/python/test_fstring_21b.txt15
-rw-r--r--tests/snippets/python/test_fstring_22a.txt14
-rw-r--r--tests/snippets/python/test_fstring_22b.txt14
-rw-r--r--tests/snippets/python/test_fstring_23a.txt11
-rw-r--r--tests/snippets/python/test_fstring_23b.txt11
-rw-r--r--tests/snippets/python/test_fstring_24a.txt23
-rw-r--r--tests/snippets/python/test_fstring_24b.txt23
-rw-r--r--tests/snippets/python/test_fstring_25a.txt24
-rw-r--r--tests/snippets/python/test_fstring_25b.txt24
-rw-r--r--tests/snippets/python/test_fstring_26a.txt20
-rw-r--r--tests/snippets/python/test_fstring_26b.txt20
-rw-r--r--tests/snippets/python/test_fstring_27a.txt11
-rw-r--r--tests/snippets/python/test_fstring_27b.txt11
-rw-r--r--tests/snippets/python/test_fstring_28a.txt11
-rw-r--r--tests/snippets/python/test_fstring_28b.txt11
-rw-r--r--tests/snippets/python/test_fstring_29a.txt15
-rw-r--r--tests/snippets/python/test_fstring_29b.txt15
-rw-r--r--tests/snippets/python/test_fstring_30a.txt16
-rw-r--r--tests/snippets/python/test_fstring_30b.txt16
-rw-r--r--tests/snippets/python/test_fstring_31a.txt15
-rw-r--r--tests/snippets/python/test_fstring_31b.txt15
-rw-r--r--tests/snippets/python/test_fstring_32a.txt15
-rw-r--r--tests/snippets/python/test_fstring_32b.txt15
-rw-r--r--tests/snippets/python/test_fstring_33a.txt15
-rw-r--r--tests/snippets/python/test_fstring_33b.txt15
-rw-r--r--tests/snippets/python/test_fstring_34a.txt20
-rw-r--r--tests/snippets/python/test_fstring_34b.txt20
-rw-r--r--tests/snippets/python/test_fstring_35a.txt15
-rw-r--r--tests/snippets/python/test_fstring_35b.txt15
-rw-r--r--tests/snippets/python/test_fstring_36a.txt16
-rw-r--r--tests/snippets/python/test_fstring_36b.txt16
-rw-r--r--tests/snippets/python/test_needs_name.txt55
-rw-r--r--tests/snippets/python/test_pep_515.txt28
-rw-r--r--tests/snippets/python/test_raw_fstring.txt46
-rw-r--r--tests/snippets/python/test_walrus_operator.txt21
76 files changed, 1450 insertions, 0 deletions
diff --git a/tests/snippets/python/test_fstring_01a.txt b/tests/snippets/python/test_fstring_01a.txt
new file mode 100644
index 00000000..406e2cc8
--- /dev/null
+++ b/tests/snippets/python/test_fstring_01a.txt
@@ -0,0 +1,25 @@
+---input---
+f'My name is {name}, my age next year is {age+1}, my anniversary is {anniversary:%A, %B %d, %Y}.'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'My name is ' Literal.String.Single
+'{' Literal.String.Interpol
+'name' Name
+'}' Literal.String.Interpol
+', my age next year is ' Literal.String.Single
+'{' Literal.String.Interpol
+'age' Name
+'+' Operator
+'1' Literal.Number.Integer
+'}' Literal.String.Interpol
+', my anniversary is ' Literal.String.Single
+'{' Literal.String.Interpol
+'anniversary' Name
+':' Literal.String.Interpol
+'%A, %B %d, %Y' Literal.String.Single
+'}' Literal.String.Interpol
+'.' Literal.String.Single
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_01b.txt b/tests/snippets/python/test_fstring_01b.txt
new file mode 100644
index 00000000..278258e2
--- /dev/null
+++ b/tests/snippets/python/test_fstring_01b.txt
@@ -0,0 +1,25 @@
+---input---
+f"My name is {name}, my age next year is {age+1}, my anniversary is {anniversary:%A, %B %d, %Y}."
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'My name is ' Literal.String.Double
+'{' Literal.String.Interpol
+'name' Name
+'}' Literal.String.Interpol
+', my age next year is ' Literal.String.Double
+'{' Literal.String.Interpol
+'age' Name
+'+' Operator
+'1' Literal.Number.Integer
+'}' Literal.String.Interpol
+', my anniversary is ' Literal.String.Double
+'{' Literal.String.Interpol
+'anniversary' Name
+':' Literal.String.Interpol
+'%A, %B %d, %Y' Literal.String.Double
+'}' Literal.String.Interpol
+'.' Literal.String.Double
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_02a.txt b/tests/snippets/python/test_fstring_02a.txt
new file mode 100644
index 00000000..359c13be
--- /dev/null
+++ b/tests/snippets/python/test_fstring_02a.txt
@@ -0,0 +1,13 @@
+---input---
+f'He said his name is {name!r}.'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'He said his name is ' Literal.String.Single
+'{' Literal.String.Interpol
+'name' Name
+'!r}' Literal.String.Interpol
+'.' Literal.String.Single
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_02b.txt b/tests/snippets/python/test_fstring_02b.txt
new file mode 100644
index 00000000..abef1600
--- /dev/null
+++ b/tests/snippets/python/test_fstring_02b.txt
@@ -0,0 +1,13 @@
+---input---
+f"He said his name is {name!r}."
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'He said his name is ' Literal.String.Double
+'{' Literal.String.Interpol
+'name' Name
+'!r}' Literal.String.Interpol
+'.' Literal.String.Double
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_03a.txt b/tests/snippets/python/test_fstring_03a.txt
new file mode 100644
index 00000000..3edee4cf
--- /dev/null
+++ b/tests/snippets/python/test_fstring_03a.txt
@@ -0,0 +1,14 @@
+---input---
+f'input={value:#06x}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'input=' Literal.String.Single
+'{' Literal.String.Interpol
+'value' Name
+':' Literal.String.Interpol
+'#06x' Literal.String.Single
+'}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_03b.txt b/tests/snippets/python/test_fstring_03b.txt
new file mode 100644
index 00000000..f7723898
--- /dev/null
+++ b/tests/snippets/python/test_fstring_03b.txt
@@ -0,0 +1,14 @@
+---input---
+f"input={value:#06x}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'input=' Literal.String.Double
+'{' Literal.String.Interpol
+'value' Name
+':' Literal.String.Interpol
+'#06x' Literal.String.Double
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_04a.txt b/tests/snippets/python/test_fstring_04a.txt
new file mode 100644
index 00000000..85619ab8
--- /dev/null
+++ b/tests/snippets/python/test_fstring_04a.txt
@@ -0,0 +1,13 @@
+---input---
+f'{"quoted string"}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+'"' Literal.String.Double
+'quoted string' Literal.String.Double
+'"' Literal.String.Double
+'}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_04b.txt b/tests/snippets/python/test_fstring_04b.txt
new file mode 100644
index 00000000..bd6308c2
--- /dev/null
+++ b/tests/snippets/python/test_fstring_04b.txt
@@ -0,0 +1,13 @@
+---input---
+f"{'quoted string'}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+"'" Literal.String.Single
+'quoted string' Literal.String.Single
+"'" Literal.String.Single
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_05a.txt b/tests/snippets/python/test_fstring_05a.txt
new file mode 100644
index 00000000..18074571
--- /dev/null
+++ b/tests/snippets/python/test_fstring_05a.txt
@@ -0,0 +1,16 @@
+---input---
+f'{f"{inner}"}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+'inner' Name
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_05b.txt b/tests/snippets/python/test_fstring_05b.txt
new file mode 100644
index 00000000..b0f3ebd8
--- /dev/null
+++ b/tests/snippets/python/test_fstring_05b.txt
@@ -0,0 +1,16 @@
+---input---
+f"{f'{inner}'}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+'inner' Name
+'}' Literal.String.Interpol
+"'" Literal.String.Single
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_06a.txt b/tests/snippets/python/test_fstring_06a.txt
new file mode 100644
index 00000000..0ba0809a
--- /dev/null
+++ b/tests/snippets/python/test_fstring_06a.txt
@@ -0,0 +1,16 @@
+# SyntaxError: f-string expression part cannot include a backslash
+
+---input---
+f'{\'quoted string\'}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+'\\' Error
+"'" Literal.String.Single
+'quoted string' Literal.String.Single
+"\\'" Literal.String.Escape
+'}' Literal.String.Single
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_06b.txt b/tests/snippets/python/test_fstring_06b.txt
new file mode 100644
index 00000000..f98b3dc2
--- /dev/null
+++ b/tests/snippets/python/test_fstring_06b.txt
@@ -0,0 +1,16 @@
+# SyntaxError: f-string expression part cannot include a backslash
+
+---input---
+f"{\"quoted string\"}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+'\\' Error
+'"' Literal.String.Double
+'quoted string' Literal.String.Double
+'\\"' Literal.String.Escape
+'}' Literal.String.Double
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_07a.txt b/tests/snippets/python/test_fstring_07a.txt
new file mode 100644
index 00000000..63942200
--- /dev/null
+++ b/tests/snippets/python/test_fstring_07a.txt
@@ -0,0 +1,17 @@
+---input---
+f'{{ {4*10} }}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{{' Literal.String.Escape
+' ' Literal.String.Single
+'{' Literal.String.Interpol
+'4' Literal.Number.Integer
+'*' Operator
+'10' Literal.Number.Integer
+'}' Literal.String.Interpol
+' ' Literal.String.Single
+'}}' Literal.String.Escape
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_07b.txt b/tests/snippets/python/test_fstring_07b.txt
new file mode 100644
index 00000000..c7e87bc7
--- /dev/null
+++ b/tests/snippets/python/test_fstring_07b.txt
@@ -0,0 +1,17 @@
+---input---
+f"{{ {4*10} }}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{{' Literal.String.Escape
+' ' Literal.String.Double
+'{' Literal.String.Interpol
+'4' Literal.Number.Integer
+'*' Operator
+'10' Literal.Number.Integer
+'}' Literal.String.Interpol
+' ' Literal.String.Double
+'}}' Literal.String.Escape
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_08a.txt b/tests/snippets/python/test_fstring_08a.txt
new file mode 100644
index 00000000..61b6cc8f
--- /dev/null
+++ b/tests/snippets/python/test_fstring_08a.txt
@@ -0,0 +1,15 @@
+---input---
+f'{{{4*10}}}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{{' Literal.String.Escape
+'{' Literal.String.Interpol
+'4' Literal.Number.Integer
+'*' Operator
+'10' Literal.Number.Integer
+'}' Literal.String.Interpol
+'}}' Literal.String.Escape
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_08b.txt b/tests/snippets/python/test_fstring_08b.txt
new file mode 100644
index 00000000..41eb13a4
--- /dev/null
+++ b/tests/snippets/python/test_fstring_08b.txt
@@ -0,0 +1,15 @@
+---input---
+f"{{{4*10}}}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{{' Literal.String.Escape
+'{' Literal.String.Interpol
+'4' Literal.Number.Integer
+'*' Operator
+'10' Literal.Number.Integer
+'}' Literal.String.Interpol
+'}}' Literal.String.Escape
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_09a.txt b/tests/snippets/python/test_fstring_09a.txt
new file mode 100644
index 00000000..3dcec51e
--- /dev/null
+++ b/tests/snippets/python/test_fstring_09a.txt
@@ -0,0 +1,14 @@
+---input---
+fr'x={4*10}'
+
+---tokens---
+'fr' Literal.String.Affix
+"'" Literal.String.Single
+'x=' Literal.String.Single
+'{' Literal.String.Interpol
+'4' Literal.Number.Integer
+'*' Operator
+'10' Literal.Number.Integer
+'}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_09b.txt b/tests/snippets/python/test_fstring_09b.txt
new file mode 100644
index 00000000..72932b29
--- /dev/null
+++ b/tests/snippets/python/test_fstring_09b.txt
@@ -0,0 +1,14 @@
+---input---
+fr"x={4*10}"
+
+---tokens---
+'fr' Literal.String.Affix
+'"' Literal.String.Double
+'x=' Literal.String.Double
+'{' Literal.String.Interpol
+'4' Literal.Number.Integer
+'*' Operator
+'10' Literal.Number.Integer
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_10a.txt b/tests/snippets/python/test_fstring_10a.txt
new file mode 100644
index 00000000..02fba2b4
--- /dev/null
+++ b/tests/snippets/python/test_fstring_10a.txt
@@ -0,0 +1,18 @@
+---input---
+f'abc {a["x"]} def'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'abc ' Literal.String.Single
+'{' Literal.String.Interpol
+'a' Name
+'[' Punctuation
+'"' Literal.String.Double
+'x' Literal.String.Double
+'"' Literal.String.Double
+']' Punctuation
+'}' Literal.String.Interpol
+' def' Literal.String.Single
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_10b.txt b/tests/snippets/python/test_fstring_10b.txt
new file mode 100644
index 00000000..46150935
--- /dev/null
+++ b/tests/snippets/python/test_fstring_10b.txt
@@ -0,0 +1,18 @@
+---input---
+f"abc {a['x']} def"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'abc ' Literal.String.Double
+'{' Literal.String.Interpol
+'a' Name
+'[' Punctuation
+"'" Literal.String.Single
+'x' Literal.String.Single
+"'" Literal.String.Single
+']' Punctuation
+'}' Literal.String.Interpol
+' def' Literal.String.Double
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_11a.txt b/tests/snippets/python/test_fstring_11a.txt
new file mode 100644
index 00000000..6116c960
--- /dev/null
+++ b/tests/snippets/python/test_fstring_11a.txt
@@ -0,0 +1,18 @@
+---input---
+f'''abc {a['x']} def'''
+
+---tokens---
+'f' Literal.String.Affix
+"'''" Literal.String.Single
+'abc ' Literal.String.Single
+'{' Literal.String.Interpol
+'a' Name
+'[' Punctuation
+"'" Literal.String.Single
+'x' Literal.String.Single
+"'" Literal.String.Single
+']' Punctuation
+'}' Literal.String.Interpol
+' def' Literal.String.Single
+"'''" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_11b.txt b/tests/snippets/python/test_fstring_11b.txt
new file mode 100644
index 00000000..77c3d6f8
--- /dev/null
+++ b/tests/snippets/python/test_fstring_11b.txt
@@ -0,0 +1,18 @@
+---input---
+f"""abc {a["x"]} def"""
+
+---tokens---
+'f' Literal.String.Affix
+'"""' Literal.String.Double
+'abc ' Literal.String.Double
+'{' Literal.String.Interpol
+'a' Name
+'[' Punctuation
+'"' Literal.String.Double
+'x' Literal.String.Double
+'"' Literal.String.Double
+']' Punctuation
+'}' Literal.String.Interpol
+' def' Literal.String.Double
+'"""' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_12a.txt b/tests/snippets/python/test_fstring_12a.txt
new file mode 100644
index 00000000..cc8eeab4
--- /dev/null
+++ b/tests/snippets/python/test_fstring_12a.txt
@@ -0,0 +1,16 @@
+---input---
+f'''{x
++1}'''
+
+---tokens---
+'f' Literal.String.Affix
+"'''" Literal.String.Single
+'{' Literal.String.Interpol
+'x' Name
+'\n' Text
+
+'+' Operator
+'1' Literal.Number.Integer
+'}' Literal.String.Interpol
+"'''" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_12b.txt b/tests/snippets/python/test_fstring_12b.txt
new file mode 100644
index 00000000..160b2d91
--- /dev/null
+++ b/tests/snippets/python/test_fstring_12b.txt
@@ -0,0 +1,16 @@
+---input---
+f"""{x
++1}"""
+
+---tokens---
+'f' Literal.String.Affix
+'"""' Literal.String.Double
+'{' Literal.String.Interpol
+'x' Name
+'\n' Text
+
+'+' Operator
+'1' Literal.Number.Integer
+'}' Literal.String.Interpol
+'"""' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_13a.txt b/tests/snippets/python/test_fstring_13a.txt
new file mode 100644
index 00000000..b556a5b6
--- /dev/null
+++ b/tests/snippets/python/test_fstring_13a.txt
@@ -0,0 +1,17 @@
+---input---
+f'''{d[0
+]}'''
+
+---tokens---
+'f' Literal.String.Affix
+"'''" Literal.String.Single
+'{' Literal.String.Interpol
+'d' Name
+'[' Punctuation
+'0' Literal.Number.Integer
+'\n' Text
+
+']' Punctuation
+'}' Literal.String.Interpol
+"'''" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_13b.txt b/tests/snippets/python/test_fstring_13b.txt
new file mode 100644
index 00000000..1e9fd60d
--- /dev/null
+++ b/tests/snippets/python/test_fstring_13b.txt
@@ -0,0 +1,17 @@
+---input---
+f"""{d[0
+]}"""
+
+---tokens---
+'f' Literal.String.Affix
+'"""' Literal.String.Double
+'{' Literal.String.Interpol
+'d' Name
+'[' Punctuation
+'0' Literal.Number.Integer
+'\n' Text
+
+']' Punctuation
+'}' Literal.String.Interpol
+'"""' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_14a.txt b/tests/snippets/python/test_fstring_14a.txt
new file mode 100644
index 00000000..de202a21
--- /dev/null
+++ b/tests/snippets/python/test_fstring_14a.txt
@@ -0,0 +1,20 @@
+---input---
+f'result: {value:{width}.{precision}}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'result: ' Literal.String.Single
+'{' Literal.String.Interpol
+'value' Name
+':' Literal.String.Interpol
+'{' Literal.String.Interpol
+'width' Name
+'}' Literal.String.Interpol
+'.' Literal.String.Single
+'{' Literal.String.Interpol
+'precision' Name
+'}' Literal.String.Interpol
+'}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_14b.txt b/tests/snippets/python/test_fstring_14b.txt
new file mode 100644
index 00000000..83aaad5e
--- /dev/null
+++ b/tests/snippets/python/test_fstring_14b.txt
@@ -0,0 +1,20 @@
+---input---
+f"result: {value:{width}.{precision}}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'result: ' Literal.String.Double
+'{' Literal.String.Interpol
+'value' Name
+':' Literal.String.Interpol
+'{' Literal.String.Interpol
+'width' Name
+'}' Literal.String.Interpol
+'.' Literal.String.Double
+'{' Literal.String.Interpol
+'precision' Name
+'}' Literal.String.Interpol
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_15a.txt b/tests/snippets/python/test_fstring_15a.txt
new file mode 100644
index 00000000..635e8791
--- /dev/null
+++ b/tests/snippets/python/test_fstring_15a.txt
@@ -0,0 +1,42 @@
+---input---
+'a' 'b' f'{x}' '{c}' f'str<{y:^4}>' 'd' 'e'
+
+---tokens---
+"'" Literal.String.Single
+'a' Literal.String.Single
+"'" Literal.String.Single
+' ' Text
+"'" Literal.String.Single
+'b' Literal.String.Single
+"'" Literal.String.Single
+' ' Text
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+'x' Name
+'}' Literal.String.Interpol
+"'" Literal.String.Single
+' ' Text
+"'" Literal.String.Single
+'{c}' Literal.String.Interpol
+"'" Literal.String.Single
+' ' Text
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'str<' Literal.String.Single
+'{' Literal.String.Interpol
+'y' Name
+':' Literal.String.Interpol
+'^4' Literal.String.Single
+'}' Literal.String.Interpol
+'>' Literal.String.Single
+"'" Literal.String.Single
+' ' Text
+"'" Literal.String.Single
+'d' Literal.String.Single
+"'" Literal.String.Single
+' ' Text
+"'" Literal.String.Single
+'e' Literal.String.Single
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_15b.txt b/tests/snippets/python/test_fstring_15b.txt
new file mode 100644
index 00000000..1a1ab251
--- /dev/null
+++ b/tests/snippets/python/test_fstring_15b.txt
@@ -0,0 +1,42 @@
+---input---
+"a" "b" f"{x}" "{c}" f"str<{y:^4}>" "d" "e"
+
+---tokens---
+'"' Literal.String.Double
+'a' Literal.String.Double
+'"' Literal.String.Double
+' ' Text
+'"' Literal.String.Double
+'b' Literal.String.Double
+'"' Literal.String.Double
+' ' Text
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+'x' Name
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+' ' Text
+'"' Literal.String.Double
+'{c}' Literal.String.Interpol
+'"' Literal.String.Double
+' ' Text
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'str<' Literal.String.Double
+'{' Literal.String.Interpol
+'y' Name
+':' Literal.String.Interpol
+'^4' Literal.String.Double
+'}' Literal.String.Interpol
+'>' Literal.String.Double
+'"' Literal.String.Double
+' ' Text
+'"' Literal.String.Double
+'d' Literal.String.Double
+'"' Literal.String.Double
+' ' Text
+'"' Literal.String.Double
+'e' Literal.String.Double
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_16a.txt b/tests/snippets/python/test_fstring_16a.txt
new file mode 100644
index 00000000..cbd4d14b
--- /dev/null
+++ b/tests/snippets/python/test_fstring_16a.txt
@@ -0,0 +1,18 @@
+---input---
+f'{i}:{d[i]}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+'i' Name
+'}' Literal.String.Interpol
+':' Literal.String.Single
+'{' Literal.String.Interpol
+'d' Name
+'[' Punctuation
+'i' Name
+']' Punctuation
+'}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_16b.txt b/tests/snippets/python/test_fstring_16b.txt
new file mode 100644
index 00000000..8ce173f0
--- /dev/null
+++ b/tests/snippets/python/test_fstring_16b.txt
@@ -0,0 +1,18 @@
+---input---
+f"{i}:{d[i]}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+'i' Name
+'}' Literal.String.Interpol
+':' Literal.String.Double
+'{' Literal.String.Interpol
+'d' Name
+'[' Punctuation
+'i' Name
+']' Punctuation
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_17a.txt b/tests/snippets/python/test_fstring_17a.txt
new file mode 100644
index 00000000..a1b5b3a5
--- /dev/null
+++ b/tests/snippets/python/test_fstring_17a.txt
@@ -0,0 +1,14 @@
+---input---
+f'x = {x:+3}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'x = ' Literal.String.Single
+'{' Literal.String.Interpol
+'x' Name
+':' Literal.String.Interpol
+'+3' Literal.String.Single
+'}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_17b.txt b/tests/snippets/python/test_fstring_17b.txt
new file mode 100644
index 00000000..5f34b174
--- /dev/null
+++ b/tests/snippets/python/test_fstring_17b.txt
@@ -0,0 +1,14 @@
+---input---
+f"x = {x:+3}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'x = ' Literal.String.Double
+'{' Literal.String.Interpol
+'x' Name
+':' Literal.String.Interpol
+'+3' Literal.String.Double
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_18a.txt b/tests/snippets/python/test_fstring_18a.txt
new file mode 100644
index 00000000..60d05123
--- /dev/null
+++ b/tests/snippets/python/test_fstring_18a.txt
@@ -0,0 +1,25 @@
+---input---
+f'{fn(lst,2)} {fn(lst,3)}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+'fn' Name
+'(' Punctuation
+'lst' Name
+',' Punctuation
+'2' Literal.Number.Integer
+')' Punctuation
+'}' Literal.String.Interpol
+' ' Literal.String.Single
+'{' Literal.String.Interpol
+'fn' Name
+'(' Punctuation
+'lst' Name
+',' Punctuation
+'3' Literal.Number.Integer
+')' Punctuation
+'}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_18b.txt b/tests/snippets/python/test_fstring_18b.txt
new file mode 100644
index 00000000..a189d00a
--- /dev/null
+++ b/tests/snippets/python/test_fstring_18b.txt
@@ -0,0 +1,25 @@
+---input---
+f"{fn(lst,2)} {fn(lst,3)}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+'fn' Name
+'(' Punctuation
+'lst' Name
+',' Punctuation
+'2' Literal.Number.Integer
+')' Punctuation
+'}' Literal.String.Interpol
+' ' Literal.String.Double
+'{' Literal.String.Interpol
+'fn' Name
+'(' Punctuation
+'lst' Name
+',' Punctuation
+'3' Literal.Number.Integer
+')' Punctuation
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_19a.txt b/tests/snippets/python/test_fstring_19a.txt
new file mode 100644
index 00000000..6e412a38
--- /dev/null
+++ b/tests/snippets/python/test_fstring_19a.txt
@@ -0,0 +1,46 @@
+---input---
+f'mapping is { {a:b for (a, b) in ((1, 2), (3, 4))} }'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'mapping is ' Literal.String.Single
+'{' Literal.String.Interpol
+' ' Text
+'{' Punctuation
+'a' Name
+':' Punctuation
+'b' Name
+' ' Text
+'for' Keyword
+' ' Text
+'(' Punctuation
+'a' Name
+',' Punctuation
+' ' Text
+'b' Name
+')' Punctuation
+' ' Text
+'in' Operator.Word
+' ' Text
+'(' Punctuation
+'(' Punctuation
+'1' Literal.Number.Integer
+',' Punctuation
+' ' Text
+'2' Literal.Number.Integer
+')' Punctuation
+',' Punctuation
+' ' Text
+'(' Punctuation
+'3' Literal.Number.Integer
+',' Punctuation
+' ' Text
+'4' Literal.Number.Integer
+')' Punctuation
+')' Punctuation
+'}' Punctuation
+' ' Text
+'}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_19b.txt b/tests/snippets/python/test_fstring_19b.txt
new file mode 100644
index 00000000..5c9d6f73
--- /dev/null
+++ b/tests/snippets/python/test_fstring_19b.txt
@@ -0,0 +1,46 @@
+---input---
+f"mapping is { {a:b for (a, b) in ((1, 2), (3, 4))} }"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'mapping is ' Literal.String.Double
+'{' Literal.String.Interpol
+' ' Text
+'{' Punctuation
+'a' Name
+':' Punctuation
+'b' Name
+' ' Text
+'for' Keyword
+' ' Text
+'(' Punctuation
+'a' Name
+',' Punctuation
+' ' Text
+'b' Name
+')' Punctuation
+' ' Text
+'in' Operator.Word
+' ' Text
+'(' Punctuation
+'(' Punctuation
+'1' Literal.Number.Integer
+',' Punctuation
+' ' Text
+'2' Literal.Number.Integer
+')' Punctuation
+',' Punctuation
+' ' Text
+'(' Punctuation
+'3' Literal.Number.Integer
+',' Punctuation
+' ' Text
+'4' Literal.Number.Integer
+')' Punctuation
+')' Punctuation
+'}' Punctuation
+' ' Text
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_20a.txt b/tests/snippets/python/test_fstring_20a.txt
new file mode 100644
index 00000000..a72a7a44
--- /dev/null
+++ b/tests/snippets/python/test_fstring_20a.txt
@@ -0,0 +1,17 @@
+---input---
+f'a={d["a"]}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'a=' Literal.String.Single
+'{' Literal.String.Interpol
+'d' Name
+'[' Punctuation
+'"' Literal.String.Double
+'a' Literal.String.Double
+'"' Literal.String.Double
+']' Punctuation
+'}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_20b.txt b/tests/snippets/python/test_fstring_20b.txt
new file mode 100644
index 00000000..556f7de8
--- /dev/null
+++ b/tests/snippets/python/test_fstring_20b.txt
@@ -0,0 +1,17 @@
+---input---
+f"a={d['a']}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'a=' Literal.String.Double
+'{' Literal.String.Interpol
+'d' Name
+'[' Punctuation
+"'" Literal.String.Single
+'a' Literal.String.Single
+"'" Literal.String.Single
+']' Punctuation
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_21a.txt b/tests/snippets/python/test_fstring_21a.txt
new file mode 100644
index 00000000..1a591003
--- /dev/null
+++ b/tests/snippets/python/test_fstring_21a.txt
@@ -0,0 +1,15 @@
+---input---
+f'a={d[a]}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'a=' Literal.String.Single
+'{' Literal.String.Interpol
+'d' Name
+'[' Punctuation
+'a' Name
+']' Punctuation
+'}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_21b.txt b/tests/snippets/python/test_fstring_21b.txt
new file mode 100644
index 00000000..7e3ed08a
--- /dev/null
+++ b/tests/snippets/python/test_fstring_21b.txt
@@ -0,0 +1,15 @@
+---input---
+f"a={d[a]}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'a=' Literal.String.Double
+'{' Literal.String.Interpol
+'d' Name
+'[' Punctuation
+'a' Name
+']' Punctuation
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_22a.txt b/tests/snippets/python/test_fstring_22a.txt
new file mode 100644
index 00000000..6a3b792f
--- /dev/null
+++ b/tests/snippets/python/test_fstring_22a.txt
@@ -0,0 +1,14 @@
+---input---
+fr'{header}:\s+'
+
+---tokens---
+'fr' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+'header' Name
+'}' Literal.String.Interpol
+':' Literal.String.Single
+'\\' Literal.String.Single
+'s+' Literal.String.Single
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_22b.txt b/tests/snippets/python/test_fstring_22b.txt
new file mode 100644
index 00000000..75a08aac
--- /dev/null
+++ b/tests/snippets/python/test_fstring_22b.txt
@@ -0,0 +1,14 @@
+---input---
+fr"{header}:\s+"
+
+---tokens---
+'fr' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+'header' Name
+'}' Literal.String.Interpol
+':' Literal.String.Double
+'\\' Literal.String.Double
+'s+' Literal.String.Double
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_23a.txt b/tests/snippets/python/test_fstring_23a.txt
new file mode 100644
index 00000000..ae944ed2
--- /dev/null
+++ b/tests/snippets/python/test_fstring_23a.txt
@@ -0,0 +1,11 @@
+---input---
+f'{a!r}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+'a' Name
+'!r}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_23b.txt b/tests/snippets/python/test_fstring_23b.txt
new file mode 100644
index 00000000..8038c8b4
--- /dev/null
+++ b/tests/snippets/python/test_fstring_23b.txt
@@ -0,0 +1,11 @@
+---input---
+f"{a!r}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+'a' Name
+'!r}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_24a.txt b/tests/snippets/python/test_fstring_24a.txt
new file mode 100644
index 00000000..9dd1e94e
--- /dev/null
+++ b/tests/snippets/python/test_fstring_24a.txt
@@ -0,0 +1,23 @@
+---input---
+f'{(lambda x: x*2)(3)}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+'(' Punctuation
+'lambda' Keyword
+' ' Text
+'x' Name
+':' Punctuation
+' ' Text
+'x' Name
+'*' Operator
+'2' Literal.Number.Integer
+')' Punctuation
+'(' Punctuation
+'3' Literal.Number.Integer
+')' Punctuation
+'}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_24b.txt b/tests/snippets/python/test_fstring_24b.txt
new file mode 100644
index 00000000..0ef51a52
--- /dev/null
+++ b/tests/snippets/python/test_fstring_24b.txt
@@ -0,0 +1,23 @@
+---input---
+f"{(lambda x: x*2)(3)}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+'(' Punctuation
+'lambda' Keyword
+' ' Text
+'x' Name
+':' Punctuation
+' ' Text
+'x' Name
+'*' Operator
+'2' Literal.Number.Integer
+')' Punctuation
+'(' Punctuation
+'3' Literal.Number.Integer
+')' Punctuation
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_25a.txt b/tests/snippets/python/test_fstring_25a.txt
new file mode 100644
index 00000000..e42453e5
--- /dev/null
+++ b/tests/snippets/python/test_fstring_25a.txt
@@ -0,0 +1,24 @@
+---input---
+extra = f'{extra},waiters:{len(self._waiters)}'
+
+---tokens---
+'extra' Name
+' ' Text
+'=' Operator
+' ' Text
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+'extra' Name
+'}' Literal.String.Interpol
+',waiters:' Literal.String.Single
+'{' Literal.String.Interpol
+'len' Name.Builtin
+'(' Punctuation
+'self' Name.Builtin.Pseudo
+'.' Operator
+'_waiters' Name
+')' Punctuation
+'}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_25b.txt b/tests/snippets/python/test_fstring_25b.txt
new file mode 100644
index 00000000..2ba4b721
--- /dev/null
+++ b/tests/snippets/python/test_fstring_25b.txt
@@ -0,0 +1,24 @@
+---input---
+extra = f"{extra},waiters:{len(self._waiters)}"
+
+---tokens---
+'extra' Name
+' ' Text
+'=' Operator
+' ' Text
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+'extra' Name
+'}' Literal.String.Interpol
+',waiters:' Literal.String.Double
+'{' Literal.String.Interpol
+'len' Name.Builtin
+'(' Punctuation
+'self' Name.Builtin.Pseudo
+'.' Operator
+'_waiters' Name
+')' Punctuation
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_26a.txt b/tests/snippets/python/test_fstring_26a.txt
new file mode 100644
index 00000000..c644d447
--- /dev/null
+++ b/tests/snippets/python/test_fstring_26a.txt
@@ -0,0 +1,20 @@
+---input---
+message.append(f" [line {lineno:2d}]")
+
+---tokens---
+'message' Name
+'.' Operator
+'append' Name
+'(' Punctuation
+'f' Literal.String.Affix
+'"' Literal.String.Double
+' [line ' Literal.String.Double
+'{' Literal.String.Interpol
+'lineno' Name
+':' Literal.String.Interpol
+'2d' Literal.String.Double
+'}' Literal.String.Interpol
+']' Literal.String.Double
+'"' Literal.String.Double
+')' Punctuation
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_26b.txt b/tests/snippets/python/test_fstring_26b.txt
new file mode 100644
index 00000000..73964104
--- /dev/null
+++ b/tests/snippets/python/test_fstring_26b.txt
@@ -0,0 +1,20 @@
+---input---
+message.append(f' [line {lineno:2d}]')
+
+---tokens---
+'message' Name
+'.' Operator
+'append' Name
+'(' Punctuation
+'f' Literal.String.Affix
+"'" Literal.String.Single
+' [line ' Literal.String.Single
+'{' Literal.String.Interpol
+'lineno' Name
+':' Literal.String.Interpol
+'2d' Literal.String.Single
+'}' Literal.String.Interpol
+']' Literal.String.Single
+"'" Literal.String.Single
+')' Punctuation
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_27a.txt b/tests/snippets/python/test_fstring_27a.txt
new file mode 100644
index 00000000..cd8bdbe2
--- /dev/null
+++ b/tests/snippets/python/test_fstring_27a.txt
@@ -0,0 +1,11 @@
+---input---
+f"{foo=}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+'foo' Name
+'=}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_27b.txt b/tests/snippets/python/test_fstring_27b.txt
new file mode 100644
index 00000000..7773ab30
--- /dev/null
+++ b/tests/snippets/python/test_fstring_27b.txt
@@ -0,0 +1,11 @@
+---input---
+f'{foo=}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+'foo' Name
+'=}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_28a.txt b/tests/snippets/python/test_fstring_28a.txt
new file mode 100644
index 00000000..6aca3216
--- /dev/null
+++ b/tests/snippets/python/test_fstring_28a.txt
@@ -0,0 +1,11 @@
+---input---
+f'{foo=!s}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+'foo' Name
+'=!s}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_28b.txt b/tests/snippets/python/test_fstring_28b.txt
new file mode 100644
index 00000000..14183eba
--- /dev/null
+++ b/tests/snippets/python/test_fstring_28b.txt
@@ -0,0 +1,11 @@
+---input---
+f"{foo=!s}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+'foo' Name
+'=!s}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_29a.txt b/tests/snippets/python/test_fstring_29a.txt
new file mode 100644
index 00000000..81715064
--- /dev/null
+++ b/tests/snippets/python/test_fstring_29a.txt
@@ -0,0 +1,15 @@
+---input---
+f"{math.pi=!f:.2f}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+'math' Name
+'.' Operator
+'pi' Name
+'=!f:' Literal.String.Interpol
+'.2f' Literal.String.Double
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_29b.txt b/tests/snippets/python/test_fstring_29b.txt
new file mode 100644
index 00000000..de5b5083
--- /dev/null
+++ b/tests/snippets/python/test_fstring_29b.txt
@@ -0,0 +1,15 @@
+---input---
+f'{math.pi=!f:.2f}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+'math' Name
+'.' Operator
+'pi' Name
+'=!f:' Literal.String.Interpol
+'.2f' Literal.String.Single
+'}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_30a.txt b/tests/snippets/python/test_fstring_30a.txt
new file mode 100644
index 00000000..f295cfe4
--- /dev/null
+++ b/tests/snippets/python/test_fstring_30a.txt
@@ -0,0 +1,16 @@
+---input---
+f"{ chr(65) =}"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+' ' Text
+'chr' Name.Builtin
+'(' Punctuation
+'65' Literal.Number.Integer
+')' Punctuation
+' ' Text
+'=}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_30b.txt b/tests/snippets/python/test_fstring_30b.txt
new file mode 100644
index 00000000..10a2af8e
--- /dev/null
+++ b/tests/snippets/python/test_fstring_30b.txt
@@ -0,0 +1,16 @@
+---input---
+f'{ chr(65) =}'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+' ' Text
+'chr' Name.Builtin
+'(' Punctuation
+'65' Literal.Number.Integer
+')' Punctuation
+' ' Text
+'=}' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_31a.txt b/tests/snippets/python/test_fstring_31a.txt
new file mode 100644
index 00000000..eac01679
--- /dev/null
+++ b/tests/snippets/python/test_fstring_31a.txt
@@ -0,0 +1,15 @@
+---input---
+f"{chr(65) = }"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+'chr' Name.Builtin
+'(' Punctuation
+'65' Literal.Number.Integer
+')' Punctuation
+' ' Text
+'= }' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_31b.txt b/tests/snippets/python/test_fstring_31b.txt
new file mode 100644
index 00000000..40702daa
--- /dev/null
+++ b/tests/snippets/python/test_fstring_31b.txt
@@ -0,0 +1,15 @@
+---input---
+f'{chr(65) = }'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+'chr' Name.Builtin
+'(' Punctuation
+'65' Literal.Number.Integer
+')' Punctuation
+' ' Text
+'= }' Literal.String.Interpol
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_32a.txt b/tests/snippets/python/test_fstring_32a.txt
new file mode 100644
index 00000000..666134c6
--- /dev/null
+++ b/tests/snippets/python/test_fstring_32a.txt
@@ -0,0 +1,15 @@
+---input---
+f'*{n=:30}*'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'*' Literal.String.Single
+'{' Literal.String.Interpol
+'n' Name
+'=:' Literal.String.Interpol
+'30' Literal.String.Single
+'}' Literal.String.Interpol
+'*' Literal.String.Single
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_32b.txt b/tests/snippets/python/test_fstring_32b.txt
new file mode 100644
index 00000000..9e087252
--- /dev/null
+++ b/tests/snippets/python/test_fstring_32b.txt
@@ -0,0 +1,15 @@
+---input---
+f"*{n=:30}*"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'*' Literal.String.Double
+'{' Literal.String.Interpol
+'n' Name
+'=:' Literal.String.Interpol
+'30' Literal.String.Double
+'}' Literal.String.Interpol
+'*' Literal.String.Double
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_33a.txt b/tests/snippets/python/test_fstring_33a.txt
new file mode 100644
index 00000000..232491b2
--- /dev/null
+++ b/tests/snippets/python/test_fstring_33a.txt
@@ -0,0 +1,15 @@
+---input---
+f'*{n=!r:30}*'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'*' Literal.String.Single
+'{' Literal.String.Interpol
+'n' Name
+'=!r:' Literal.String.Interpol
+'30' Literal.String.Single
+'}' Literal.String.Interpol
+'*' Literal.String.Single
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_33b.txt b/tests/snippets/python/test_fstring_33b.txt
new file mode 100644
index 00000000..1481e811
--- /dev/null
+++ b/tests/snippets/python/test_fstring_33b.txt
@@ -0,0 +1,15 @@
+---input---
+f"*{n=!r:30}*"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'*' Literal.String.Double
+'{' Literal.String.Interpol
+'n' Name
+'=!r:' Literal.String.Interpol
+'30' Literal.String.Double
+'}' Literal.String.Interpol
+'*' Literal.String.Double
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_34a.txt b/tests/snippets/python/test_fstring_34a.txt
new file mode 100644
index 00000000..6bd510a9
--- /dev/null
+++ b/tests/snippets/python/test_fstring_34a.txt
@@ -0,0 +1,20 @@
+---input---
+f"*{f'{n=}':30}*"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'*' Literal.String.Double
+'{' Literal.String.Interpol
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'{' Literal.String.Interpol
+'n' Name
+'=}' Literal.String.Interpol
+"'" Literal.String.Single
+':' Literal.String.Interpol
+'30' Literal.String.Double
+'}' Literal.String.Interpol
+'*' Literal.String.Double
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_34b.txt b/tests/snippets/python/test_fstring_34b.txt
new file mode 100644
index 00000000..4cb7e631
--- /dev/null
+++ b/tests/snippets/python/test_fstring_34b.txt
@@ -0,0 +1,20 @@
+---input---
+f'*{f"{n=}":30}*'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'*' Literal.String.Single
+'{' Literal.String.Interpol
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'{' Literal.String.Interpol
+'n' Name
+'=}' Literal.String.Interpol
+'"' Literal.String.Double
+':' Literal.String.Interpol
+'30' Literal.String.Single
+'}' Literal.String.Interpol
+'*' Literal.String.Single
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_35a.txt b/tests/snippets/python/test_fstring_35a.txt
new file mode 100644
index 00000000..f09edc18
--- /dev/null
+++ b/tests/snippets/python/test_fstring_35a.txt
@@ -0,0 +1,15 @@
+---input---
+f'*{n=:+<30}*'
+
+---tokens---
+'f' Literal.String.Affix
+"'" Literal.String.Single
+'*' Literal.String.Single
+'{' Literal.String.Interpol
+'n' Name
+'=:' Literal.String.Interpol
+'+<30' Literal.String.Single
+'}' Literal.String.Interpol
+'*' Literal.String.Single
+"'" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_35b.txt b/tests/snippets/python/test_fstring_35b.txt
new file mode 100644
index 00000000..794f7b69
--- /dev/null
+++ b/tests/snippets/python/test_fstring_35b.txt
@@ -0,0 +1,15 @@
+---input---
+f"*{n=:+<30}*"
+
+---tokens---
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'*' Literal.String.Double
+'{' Literal.String.Interpol
+'n' Name
+'=:' Literal.String.Interpol
+'+<30' Literal.String.Double
+'}' Literal.String.Interpol
+'*' Literal.String.Double
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_36a.txt b/tests/snippets/python/test_fstring_36a.txt
new file mode 100644
index 00000000..4b6ab230
--- /dev/null
+++ b/tests/snippets/python/test_fstring_36a.txt
@@ -0,0 +1,16 @@
+---input---
+
+f'''{foo
+ = !s:20}'''
+
+---tokens---
+'f' Literal.String.Affix
+"'''" Literal.String.Single
+'{' Literal.String.Interpol
+'foo' Name
+'\n ' Text
+'= !s:' Literal.String.Interpol
+'20' Literal.String.Single
+'}' Literal.String.Interpol
+"'''" Literal.String.Single
+'\n' Text
diff --git a/tests/snippets/python/test_fstring_36b.txt b/tests/snippets/python/test_fstring_36b.txt
new file mode 100644
index 00000000..abc9cf3e
--- /dev/null
+++ b/tests/snippets/python/test_fstring_36b.txt
@@ -0,0 +1,16 @@
+---input---
+
+f"""{foo
+ = !s:20}"""
+
+---tokens---
+'f' Literal.String.Affix
+'"""' Literal.String.Double
+'{' Literal.String.Interpol
+'foo' Name
+'\n ' Text
+'= !s:' Literal.String.Interpol
+'20' Literal.String.Double
+'}' Literal.String.Interpol
+'"""' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_needs_name.txt b/tests/snippets/python/test_needs_name.txt
new file mode 100644
index 00000000..60c782c5
--- /dev/null
+++ b/tests/snippets/python/test_needs_name.txt
@@ -0,0 +1,55 @@
+# Tests that '@' is recognized as an Operator
+
+---input---
+S = (H @ beta - r).T @ inv(H @ V @ H.T) @ (H @ beta - r)
+
+---tokens---
+'S' Name
+' ' Text
+'=' Operator
+' ' Text
+'(' Punctuation
+'H' Name
+' ' Text
+'@' Operator
+' ' Text
+'beta' Name
+' ' Text
+'-' Operator
+' ' Text
+'r' Name
+')' Punctuation
+'.' Operator
+'T' Name
+' ' Text
+'@' Operator
+' ' Text
+'inv' Name
+'(' Punctuation
+'H' Name
+' ' Text
+'@' Operator
+' ' Text
+'V' Name
+' ' Text
+'@' Operator
+' ' Text
+'H' Name
+'.' Operator
+'T' Name
+')' Punctuation
+' ' Text
+'@' Operator
+' ' Text
+'(' Punctuation
+'H' Name
+' ' Text
+'@' Operator
+' ' Text
+'beta' Name
+' ' Text
+'-' Operator
+' ' Text
+'r' Name
+')' Punctuation
+'\n' Text
diff --git a/tests/snippets/python/test_pep_515.txt b/tests/snippets/python/test_pep_515.txt
new file mode 100644
index 00000000..a5f2f358
--- /dev/null
+++ b/tests/snippets/python/test_pep_515.txt
@@ -0,0 +1,28 @@
+# Tests that the lexer can parse numeric literals with underscores
+
+---input---
+1_000_000
+1_000.000_001
+1_000e1_000j
+0xCAFE_F00D
+0b_0011_1111_0100_1110
+0o_777_123
+
+---tokens---
+'1_000_000' Literal.Number.Integer
+'\n' Text
+
+'1_000.000_001' Literal.Number.Float
+'\n' Text
+
+'1_000e1_000j' Literal.Number.Float
+'\n' Text
+
+'0xCAFE_F00D' Literal.Number.Hex
+'\n' Text
+
+'0b_0011_1111_0100_1110' Literal.Number.Bin
+'\n' Text
+
+'0o_777_123' Literal.Number.Oct
+'\n' Text
diff --git a/tests/snippets/python/test_raw_fstring.txt b/tests/snippets/python/test_raw_fstring.txt
new file mode 100644
index 00000000..0dd51c1e
--- /dev/null
+++ b/tests/snippets/python/test_raw_fstring.txt
@@ -0,0 +1,46 @@
+# Tests that the lexer can parse raw f-strings
+
+---input---
+rf"m_\nu = x"
+
+f"m_\nu = {x}"
+
+rf"m_{{\nu}} = {x}"
+
+---tokens---
+'rf' Literal.String.Affix
+'"' Literal.String.Double
+'m_' Literal.String.Double
+'\\' Literal.String.Double
+'nu = x' Literal.String.Double
+'"' Literal.String.Double
+'\n' Text
+
+'\n' Text
+
+'f' Literal.String.Affix
+'"' Literal.String.Double
+'m_' Literal.String.Double
+'\\n' Literal.String.Escape
+'u = ' Literal.String.Double
+'{' Literal.String.Interpol
+'x' Name
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
+
+'\n' Text
+
+'rf' Literal.String.Affix
+'"' Literal.String.Double
+'m_' Literal.String.Double
+'{{' Literal.String.Escape
+'\\' Literal.String.Double
+'nu' Literal.String.Double
+'}}' Literal.String.Escape
+' = ' Literal.String.Double
+'{' Literal.String.Interpol
+'x' Name
+'}' Literal.String.Interpol
+'"' Literal.String.Double
+'\n' Text
diff --git a/tests/snippets/python/test_walrus_operator.txt b/tests/snippets/python/test_walrus_operator.txt
new file mode 100644
index 00000000..05935ec9
--- /dev/null
+++ b/tests/snippets/python/test_walrus_operator.txt
@@ -0,0 +1,21 @@
+# Tests that ':=' is recognized as an Operator
+
+---input---
+if (a := 2) > 4:
+
+---tokens---
+'if' Keyword
+' ' Text
+'(' Punctuation
+'a' Name
+' ' Text
+':=' Operator
+' ' Text
+'2' Literal.Number.Integer
+')' Punctuation
+' ' Text
+'>' Operator
+' ' Text
+'4' Literal.Number.Integer
+':' Punctuation
+'\n' Text