jenkins-bot submitted this change.

View Change

Approvals: Xqt: Looks good to me, approved Matěj Suchánek: Looks good to me, but someone else must approve jenkins-bot: Verified
[IMPR] Implement a new and easier color format for Pywikibot

The old color format is like 'this is a \03{green}colored\03{default} text'.
With Python 3 curly brackets are parts of the default format string. Using
it needs strings like
'this is a \03{{green}}{color}colored\03{{default}} text'
which needs double brackets.

A color_format method was introduced to omit the \03 escape sequence which
allows strings like
color_format('this is a {green}{col} colored{default} text', col='red')
but be aware the 'color' key is reserved for a color key and will be
escaped then. In short: it is not very helpful to simplify colored text
because each string must be passed through that function.

Now a new color pattern is implemented which can be used directly with output
methods and does not bother any format string. The sample above can be
written like

'this is a <<green>>{color} colored<<default>> text'.format(color='red')

The advantages are
- the escape sequence \03{...} is replaced by <<...>>
- the color_format method will be deprecated, there is no benefit to
keep it.
- the old and new implementation will be supported both for a while
but must not be mixed in the same output statement
- a usage sample is made in

Change-Id: I5bfcaac8ef12a65dab1a2515809373633e1706b1
M pywikibot/userinterfaces/
2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/ b/
index 5e9d14a..6fddcec 100755
--- a/
+++ b/
@@ -293,7 +293,6 @@
"""Search for similar filenames in the given script paths."""
from pywikibot import config, input_choice, output
from import QuitKeyboardInterrupt, ShowingListOption
- from import color_format

assert config.pwb_close_matches > 0, \
'config.pwb_close_matches must be greater than 0'
@@ -324,11 +323,10 @@
if len(similar_scripts) == 1:
script = similar_scripts[0]
wait_time = config.pwb_autostart_waittime
- output(color_format(
- 'NOTE: Starting the most similar script '
- '{lightyellow}{0}.py{default}\n'
- ' in {1} seconds; type CTRL-C to stop.',
- script, wait_time))
+ output('NOTE: Starting the most similar script '
+ '<<lightyellow>>{}.py<<default>>\n'
+ ' in {} seconds; type CTRL-C to stop.'
+ .format(script, wait_time))
sleep(wait_time) # Wait a bit to let it be cancelled
except KeyboardInterrupt:
diff --git a/pywikibot/userinterfaces/ b/pywikibot/userinterfaces/
index 9a9b443..0444206 100644
--- a/pywikibot/userinterfaces/
+++ b/pywikibot/userinterfaces/
@@ -50,9 +50,9 @@

-_color_pat = '{}|previous'.format('|'.join(colors))
-colorTagR = re.compile('\03{{((:?{cpat});?(:?{cpat})?)}}'
- .format(cpat=_color_pat))
+_color_pat = '((:?{0});?(:?{0})?)'.format('|'.join(colors + ['previous']))
+old_colorTagR = re.compile('\03{{{cpat}}}'.format(cpat=_color_pat))
+new_colorTagR = re.compile('<<{cpat}>>'.format(cpat=_color_pat))

class UI(ABUIC):
@@ -195,7 +195,14 @@
# Color tags might be cascaded, e.g. because of transliteration.
# Therefore we need this stack.
color_stack = ['default']
- text_parts = colorTagR.split(text) + ['default']
+ old_parts = old_colorTagR.split(text)
+ new_parts = new_colorTagR.split(text)
+ if min(len(old_parts), len(new_parts)) > 1:
+ raise ValueError('Old color format must not be mixed with new '
+ 'color format. Found:\n'
+ + text.replace('\03', '\\03'))
+ text_parts = old_parts if len(old_parts) > 1 else new_parts
+ text_parts += ['default']
# match.split() includes every regex group; for each matched color
# fg_col:b_col, fg_col and bg_col are added to the resulting list.
len_text_parts = len(text_parts[::4])

To view, visit change 779851. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I5bfcaac8ef12a65dab1a2515809373633e1706b1
Gerrit-Change-Number: 779851
Gerrit-PatchSet: 16
Gerrit-Owner: Xqt <>
Gerrit-Reviewer: Matěj Suchánek <>
Gerrit-Reviewer: Xqt <>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged