Commit: runtime(python): Update syntax, improve pythonNumber pattern performance

0 views
Skip to first unread message

Christian Brabandt

unread,
Mar 11, 2026, 4:02:00 PM (21 hours ago) Mar 11
to vim...@googlegroups.com
runtime(python): Update syntax, improve pythonNumber pattern performance

Commit: https://github.com/vim/vim/commit/2cf18fcc240030880bbd138e5174e436a3f20823
Author: Doug Kearns <dougk...@gmail.com>
Date: Wed Mar 11 19:47:55 2026 +0000

runtime(python): Update syntax, improve pythonNumber pattern performance

- Improve the performance of all pythonNumber patterns by unrolling
digit/underscore sequence loops.
- Split the float literal pattern into two simpler patterns.

fixes: #19625 (Reported by James McCoy)
closes: #19630

Signed-off-by: Doug Kearns <dougk...@gmail.com>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/syntax/python.vim b/runtime/syntax/python.vim
index 456a9825a..e48346899 100644
--- a/runtime/syntax/python.vim
+++ b/runtime/syntax/python.vim
@@ -5,6 +5,7 @@
" 2025 Sep 25 by Vim Project: fix wrong type highlighting #18394
" 2025 Dec 03 by Vim Project: highlight t-strings #18679
" 2026 Jan 26 by Vim Project: highlight constants #18922
+" 2026 Mar 11 by Vim Project: fix number performance #19630
" Credits: Neil Schemenauer <n...@python.ca>
" Dmitry Vasiliev
" Rob B
@@ -270,16 +271,21 @@ syn match pythonEscape "\$"
" https://docs.python.org/reference/lexical_analysis.html#numeric-literals
if !exists("python_no_number_highlight")
" numbers (including complex)
- syn match pythonNumber "\<0[oO]\%(_\=\o\)\+\>"
- syn match pythonNumber "\<0[xX]\%(_\=\x\)\+\>"
- syn match pythonNumber "\<0[bB]\%(_\=[01]\)\+\>"
- syn match pythonNumber "\<\%([1-9]\%(_\=\d\)*\|0\+\%(_\=0\)*\)\>"
- syn match pythonNumber "\<\d\%(_\=\d\)*[jJ]\>"
- syn match pythonNumber "\<\d\%(_\=\d\)*[eE][+-]\=\d\%(_\=\d\)*[jJ]\=\>"
+ syn match pythonNumber "\<0[oO]_\=\o\+\%(_\o\+\)*\>"
+ syn match pythonNumber "\<0[xX]_\=\x\+\%(_\x\+\)*\>"
+ syn match pythonNumber "\<0[bB]_\=[01]\+\%(_[01]\+\)*\>"
+ syn match pythonNumber "\<\%([1-9]\d*\%(_\d\+\)*\|0\+\%(_0\+\)*\)\>"
+ syn match pythonNumber "\<\d\+\%(_\d\+\)*[jJ]\>"
+ syn match pythonNumber "\<\d\+\%(_\d\+\)*[eE][+-]\=\d\+\%(_\d\+\)*[jJ]\=\>"
+ " \d\.
syn match pythonNumber
- \ "\<\d\%(_\=\d\)*\.\%([eE][+-]\=\d\%(_\=\d\)*\)\=[jJ]\=\%(\W\|$\)\@="
+ \ "\<\d\+\%(_\d\+\)*\.\%([eE][+-]\=\d\+\%(_\d\+\)*\)\=[jJ]\=\%(\W\|$\)\@="
+ " \d\.\d
syn match pythonNumber
- \ "\%(^\|\W\)\@1<=\%(\d\%(_\=\d\)*\)\=\.\d\%(_\=\d\)*\%([eE][+-]\=\d\%(_\=\d\)*\)\=[jJ]\=\>"
+ \ "\<\d\+\%(_\d\+\)*\.\d\+\%(_\d\+\)*\%([eE][+-]\=\d\+\%(_\d\+\)*\)\=[jJ]\=\>"
+ " \.\d
+ syn match pythonNumber
+ \ "\%(^\|\W\)\@1<=\.\d\+\%(_\d\+\)*\%([eE][+-]\=\d\+\%(_\d\+\)*\)\=[jJ]\=\>"
endif

" Group the built-ins in the order in the 'Python Library Reference' for
diff --git a/runtime/syntax/testdir/dumps/python_numbers_00.dump b/runtime/syntax/testdir/dumps/python_numbers_00.dump
new file mode 100644
index 000000000..6f6506400
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/python_numbers_00.dump
@@ -0,0 +1,20 @@
+>#+0#0000e05#ffffff0| |N|u|m|e|r|i|c| |l|i|t|e|r|a|l|s| +0#0000000&@56
+|#+0#0000e05&| |h|t@1|p|s|:|/@1|d|o|c|s|.|p|y|t|h|o|n|.|o|r|g|/|3|/|r|e|f|e|r|e|n|c|e|/|l|e|x|i|c|a|l|_|a|n|a|l|y|s|i|s|.|h|t|m|l|#|n|u|m|e|r|i|c|-|l|i|t|e|r|a|l
+|s| +0#0000000&@73
+@75
+|#+0#0000e05&| |I|n|t|e|g|e|r| |l|i|t|e|r|a|l|s| +0#0000000&@56
+@75
+|7+0#e000002&| +0#0000000&@73
+|3+0#e000002&| +0#0000000&@73
+|2+0#e000002&|1|4|7|4|8|3|6|4|7| +0#0000000&@64
+@75
+|7+0#e000002&|9|2@1|8|1|6|2|5|1|4|2|6|4|3@1|7|5|9|3|5|4|3|9|5|0|3@1|6|7|9|2@1|8|1|6|2|5|1|4|2|6|4|3@1|7|5|9|3|5|4|3|9|5|0|3@1|6| +0#0000000&@16
+@75
+|1+0#e000002&|0@1|_|0@2|_|0@2|_|0@2| +0#0000000&@59
+|1+0#e000002&|0@10| +0#0000000&@62
+|1+0#e000002&|_|0@1|_|0@1|_|0@1|_|0@1|_|0@2| +0#0000000&@57
+@75
+|0+0#e000002&|b|1|0@1|1@1|0|1@2| +0#0000000&@63
+|0+0#e000002&|b|_|1@2|0|_|0|1|0|1| +0#0000000&@62
+|0+0#e000002&|o|1|7@1| +0#0000000&@69
+@57|1|,|1| @10|T|o|p|
diff --git a/runtime/syntax/testdir/dumps/python_numbers_01.dump b/runtime/syntax/testdir/dumps/python_numbers_01.dump
new file mode 100644
index 000000000..eda3caae3
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/python_numbers_01.dump
@@ -0,0 +1,20 @@
+|1+0#e000002#ffffff0|0@10| +0#0000000&@62
+|1+0#e000002&|_|0@1|_|0@1|_|0@1|_|0@1|_|0@2| +0#0000000&@57
+@75
+|0+0#e000002&|b|1|0@1|1@1|0|1@2| +0#0000000&@63
+|0+0#e000002&|b|_|1@2|0|_|0|1|0|1| +0#0000000&@62
+>0+0#e000002&|o|1|7@1| +0#0000000&@69
+|0+0#e000002&|o|3|7@1| +0#0000000&@69
+|0+0#e000002&|x|d|e|a|d|b|e@1|f| +0#0000000&@64
+|0+0#e000002&|x|D|e|a|d|_|B|e@1|f| +0#0000000&@63
+@75
+|#+0#0000e05&| |F|l|o|a|t|i|n|g|-|p|o|i|n|t| |l|i|t|e|r|a|l|s| +0#0000000&@49
+@75
+|2+0#e000002&|.|7|1|8|2|8| +0#0000000&@67
+|4+0#e000002&|.|0| +0#0000000&@71
+@75
+|9+0#e000002&|6|_|4|8|5|.|3@1|2|_|1|2|3| +0#0000000&@60
+|3+0#e000002&|.|1|4|_|1|5|_|9|3| +0#0000000&@64
+@75
+|1+0#e000002&|0|.| +0#0000000&@1|#+0#0000e05&| |(|e|q|u|i|v|a|l|e|n|t| |t|o| |1|0|.|0|)| +0#0000000&@47
+@57|1|8|,|1| @9|2|5|%|
diff --git a/runtime/syntax/testdir/dumps/python_numbers_02.dump b/runtime/syntax/testdir/dumps/python_numbers_02.dump
new file mode 100644
index 000000000..5ea9c1e74
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/python_numbers_02.dump
@@ -0,0 +1,20 @@
+|1+0#e000002#ffffff0|0|.| +0#0000000&@1|#+0#0000e05&| |(|e|q|u|i|v|a|l|e|n|t| |t|o| |1|0|.|0|)| +0#0000000&@47
+|.+0#e000002&|0@1|1| +0#0000000&@1|#+0#0000e05&| |(|e|q|u|i|v|a|l|e|n|t| |t|o| |0|.|0@1|1|)| +0#0000000&@45
+@75
+|1+0#e000002&|.|0|e|3| +0#0000000&@1|#+0#0000e05&| |(|r|e|p|r|e|s|e|n|t|s| |1|.|0|×|1|0|³|,| |o|r| |1|0@2|.|0|)| +0#0000000&@34
+|1+0#e000002&|.|1|6@1|e|-|5| +0#0000000&@1|#+0#0000e05&| |(|r|e|p|r|e|s|e|n|t|s| |1|.|1|6@1|×|1|0|⁻|⁵|,| |o|r| |0|.|0@3|1@1|6@1|)| +0#0000000&@24
+>6+0#e000002&|.|0|2@1|1|4|0|7|6|e|+|2|3| +0#0000000&@1|#+0#0000e05&| |(|r|e|p|r|e|s|e|n|t|s| |6|.|0|2@1|1|4|0|7|6|×|1|0|²|³|,| |o|r| |6|0|2@1|1|4|0|7|6|0@14|.
+|)| +0#0000000&@73
+@75
+|1+0#e000002&|e|3| +0#0000000&@1|#+0#0000e05&| |(|e|q|u|i|v|a|l|e|n|t| |t|o| |1|.|e|3| |a|n|d| |1|.|0|e|3|)| +0#0000000&@37
+|0+0#e000002&|e|0| +0#0000000&@1|#+0#0000e05&| |(|e|q|u|i|v|a|l|e|n|t| |t|o| |0|.|)| +0#0000000&@49
+@75
+|#+0#0000e05&| |I|m|a|g|i|n|a|r|y| |l|i|t|e|r|a|l|s| +0#0000000&@54
+@75
+|3+0#e000002&|++0#0000000&|4+0#e000002&|.|2|j| +0#0000000&@68
+@75
+|3+0#e000002&| +0#0000000&|+| |4+0#e000002&|.|2|j| +0#0000000&@66
+@75
+|4+0#e000002&|.|2|j| +0#0000000&@70
+|3+0#e000002&|.|1|4|j| +0#0000000&@69
+@57|3|6|,|1| @9|6|2|%|
diff --git a/runtime/syntax/testdir/dumps/python_numbers_03.dump b/runtime/syntax/testdir/dumps/python_numbers_03.dump
new file mode 100644
index 000000000..8b42f433f
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/python_numbers_03.dump
@@ -0,0 +1,20 @@
+|3+0#e000002#ffffff0|.|1|4|j| +0#0000000&@69
+|1+0#e000002&|0|.|j| +0#0000000&@70
+|.+0#e000002&|0@1|1|j| +0#0000000&@69
+|1+0#e000002&|e|1|0@1|j| +0#0000000&@68
+|3+0#e000002&|.|1|4|e|-|1|0|j| +0#0000000&@65
+>3+0#e000002&|.|1|4|_|1|5|_|9|3|j| +0#0000000&@63
+@75
+|1+0#e000002&|0|j| +0#0000000&@71
+|0+0#e000002&|j| +0#0000000&@72
+|1+0#e000002&|0@23|j| +0#0000000&@2|#+0#0000e05&| |e|q|u|i|v|a|l|e|n|t| |t|o| |1|e|+|2|4|j| +0#0000000&@23
+@75
+|3+0#e000002&|.|1|4|J| +0#0000000&@2|#+0#0000e05&| |e|q|u|i|v|a|l|e|n|t| |t|o| |3|.|1|4|j| +0#0000000&@45
+@75
+@75
+@75
+|#+0#0000e05&| |I|s@1|u|e| |#|1|9|6|2|5| |(|r|u|n|t|i|m|e|(|p|y|t|h|o|n|)|:| |L|a|r|g|e| |n|u|m|b|e|r| |l|i|t|e|r|a|l|s| |c|a|u|s|e| |E|3|6|3|)| +0#0000000&@8
+@75
+|N|=|2+0#e000002&|1|4|0|3|2|4|6|5|0|2|4|0|7|4@1|9|6|1|2|6|4@1|2|3|0|7|2|8|3|9|3@2|5|6|3|0@1|8|6|1|4|7|1|5|1|4@1|7|5@1|0|1|7@1|9|7@1|5|4|9|2|0|8@1|1|4|1|8|0|2|3
+|4@1|7|1|4|0|1|3|6@1|4|3@1|4|5@1|1|9|0|9|5|8|0|4|6|7|9|6|1|0|9@1|2|8|5|1|8|7|2|4|7|0|9|1|4|5|8|7|6|8|7|3|9|6|2|6|1|9|2|1|5@1|7|3|6|3|0|4|7|4|5|4|@+0#4040ff13&@2
+| +0#0000000&@56|5|3|,|1| @9|9|5|%|
diff --git a/runtime/syntax/testdir/dumps/python_numbers_04.dump b/runtime/syntax/testdir/dumps/python_numbers_04.dump
new file mode 100644
index 000000000..2a70defa9
--- /dev/null
+++ b/runtime/syntax/testdir/dumps/python_numbers_04.dump
@@ -0,0 +1,20 @@
+|N+0&#ffffff0|=|2+0#e000002&|1|4|0|3|2|4|6|5|0|2|4|0|7|4@1|9|6|1|2|6|4@1|2|3|0|7|2|8|3|9|3@2|5|6|3|0@1|8|6|1|4|7|1|5|1|4@1|7|5@1|0|1|7@1|9|7@1|5|4|9|2|0|8@1|1|4|1|8|0|2|3
+|4@1|7|1|4|0|1|3|6@1|4|3@1|4|5@1|1|9|0|9|5|8|0|4|6|7|9|6|1|0|9@1|2|8|5|1|8|7|2|4|7|0|9|1|4|5|8|7|6|8|7|3|9|6|2|6|1|9|2|1|5@1|7|3|6|3|0|4|7|4|5|4|7@1|0
+|5|2|0|8|0|5|1@1|9|0|5|6|4|9|3|1|0|6@1|8|1| +0#0000000&@53
+> @74
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|6@1|,|0|-|1| @7|B|o|t|
Reply all
Reply to author
Forward
0 new messages