[MediaWiki-commits] [Gerrit] [FEAT] color_format to ignore valid colors - change (pywikibot/core)
jenkins-bot has submitted this change and it was merged. Change subject: [FEAT] color_format to ignore valid colors .. [FEAT] color_format to ignore valid colors This allows to add colors to strings which will be filled using format. Instead of calling 'str'.format(…), color_format('str', …) is called. That uses the `_ColorFormatter` class which parses the text differently and skips color fields. It also checks that the color fields are used without conversion and format spec. The `\03` marker becomes optional and is added if missing and if it may not be present anywhere else than in front of color field. Change-Id: Ib354fb80180b0e421a18474cc67d7ee10cda3745 --- M pywikibot/bot.py M pywikibot/tools/formatter.py M tests/tools_formatter_tests.py 3 files changed, 113 insertions(+), 5 deletions(-) Approvals: John Vandenberg: Looks good to me, approved jenkins-bot: Verified diff --git a/pywikibot/bot.py b/pywikibot/bot.py index c0a119c..25ed2b0 100644 --- a/pywikibot/bot.py +++ b/pywikibot/bot.py @@ -101,6 +101,7 @@ LoggingFormatter as _LoggingFormatter, RotatingFileHandler, ) +from pywikibot.tools.formatter import color_format if not PY2: unicode = str @@ -742,17 +743,16 @@ '\03{default}' + text[rng[1]: rng[1] + self.context]) question = 'Should the link ' else: -question = 'Should the link \03{{lightred}}{0}\03{{default}} ' +question = 'Should the link {lightred}{0}{default} ' if self._new is False: question += 'be unlinked?' else: -question += ('target to ' - '\03lightpurple{0}\03default?').format( - self._new.canonical_title()) +question += color_format('target to {lightpurple}{0}{default}?', + self._new.canonical_title()) choice = pywikibot.input_choice( -question.format(self._old.canonical_title()), +color_format(question, self._old.canonical_title()), choices, default=self._default, automatic_quit=self._quit) return self.handle_answer(choice) diff --git a/pywikibot/tools/formatter.py b/pywikibot/tools/formatter.py index d2f15e2..151e4d9 100644 --- a/pywikibot/tools/formatter.py +++ b/pywikibot/tools/formatter.py @@ -9,9 +9,13 @@ __version__ = '$Id$' +import inspect import math +from string import Formatter + from pywikibot.logging import output +from pywikibot.userinterfaces.terminal_interface_base import colors class SequenceOutputter(object): @@ -56,3 +60,63 @@ def output(self): """Output the text of the current sequence.""" output(self.format_list()) + + +class _ColorFormatter(Formatter): + +"""Special string formatter which skips colors.""" + +colors = set(colors) + +def __init__(self): +"""Create new instance and store the stack depth.""" +super(_ColorFormatter, self).__init__() +self._depth = len(inspect.stack()) + +def parse(self, format_string): +"""Yield results similar to parse but skip colors.""" +previous_literal = '' +for literal, field, spec, conv in super(_ColorFormatter, self).parse( +format_string): +if field in self.colors: +if spec: +raise ValueError( +'Color field "{0}" in "{1}" uses format spec ' +'information "{2}"'.format(field, format_string, spec)) +elif conv: +raise ValueError( +'Color field "{0}" in "{1}" uses conversion ' +'information "{2}"'.format(field, format_string, conv)) +else: +if not literal or literal[-1] != '\03': +literal += '\03' +if '\03' in literal[:-1]: +raise ValueError(r'Literal text in {0} contains ' + r'\03'.format(format_string)) +previous_literal += literal + '{' + field + '}' +else: +if '\03' in literal: +raise ValueError(r'Literal text in {0} contains ' + r'\03'.format(format_string)) +yield previous_literal + literal, field, spec, conv +previous_literal = '' +if previous_literal: +yield previous_literal, None, None, None + +def vformat(self, format_string, args, kwargs): +"""Return the normal format result but verify no colors are keywords.""" +if self.colors.intersection(kwargs): # kwargs use colors +raise ValueError('Keyword argument(s) use valid color(s): ' + + '", "'.join(self.colors.intersection(kwargs))) +
[MediaWiki-commits] [Gerrit] [FEAT] color_format to ignore valid colors - change (pywikibot/core)
XZise has uploaded a new change for review. https://gerrit.wikimedia.org/r/222907 Change subject: [FEAT] color_format to ignore valid colors .. [FEAT] color_format to ignore valid colors This allows to add colors to strings which will be filled using format. Instead of calling 'str'.format(…), color_format('str', …) is called. That adds all valid colors as keyword arguments so that they are replaced by themselves. Change-Id: Ib354fb80180b0e421a18474cc67d7ee10cda3745 --- M pywikibot/bot.py M tests/bot_tests.py 2 files changed, 43 insertions(+), 5 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/pywikibot/core refs/changes/07/222907/1 diff --git a/pywikibot/bot.py b/pywikibot/bot.py index 57e8ec0..f09dd18 100644 --- a/pywikibot/bot.py +++ b/pywikibot/bot.py @@ -49,6 +49,7 @@ ChoiceException, QuitKeyboardInterrupt, ) from pywikibot.tools import deprecated, deprecated_args, PY2, PYTHON_VERSION +from pywikibot.userinterfaces.terminal_interface_base import colors if not PY2: unicode = str @@ -84,6 +85,19 @@ def __init__(self, stop=False): """Constructor.""" self.stop = stop + + +def color_format(text, *args, **kwargs): +"""Do C{str.format} without having to worry about colors.""" +valid_colors = set(colors) +if valid_colors.intersection(kwargs): # kwargs use colors +raise ValueError('Keyword argument(s) should not use valid color(s): ' + + '", "'.join(valid_colors.intersection(kwargs))) +else: +# Add all colors to kwargs to replace nothing +for color in valid_colors: +kwargs[color] = '{{{0}}}'.format(color) +return text.format(*args, **kwargs) # Logging module configuration @@ -930,17 +944,16 @@ '\03{default}' + text[rng[1]: rng[1] + self.context]) question = 'Should the link ' else: -question = 'Should the link \03{{lightred}}{0}\03{{default}} ' +question = 'Should the link \03{lightred}{0}\03{default} ' if self._new is False: question += 'be unlinked?' else: -question += ('target to ' - '\03lightpurple{0}\03default?').format( - self._new.canonical_title()) +question += color_format('target to \03{lightpurple}{0}\03{default}?', + self._new.canonical_title()) choice = pywikibot.input_choice( -question.format(self._old.canonical_title()), +color_format(question, self._old.canonical_title()), choices, default=self._default, automatic_quit=self._quit) return self.handle_answer(choice) diff --git a/tests/bot_tests.py b/tests/bot_tests.py index 4764e79..5227de4 100644 --- a/tests/bot_tests.py +++ b/tests/bot_tests.py @@ -19,6 +19,31 @@ ) +class ColorFormatTestCase(TestCase): + +"""Test color_format function in bot module.""" + +net = False + +def test_no_colors(self): +"""Test without colors in template string.""" +self.assertEqual(pywikibot.bot.color_format('42'), '42') +self.assertEqual(pywikibot.bot.color_format('{0}', 42), '42') +self.assertEqual(pywikibot.bot.color_format('{ans}', ans=42), '42') + +def test_colors(self): +"""Test with colors in template string.""" +self.assertEqual(pywikibot.bot.color_format('{0}{black}', 42), + '42{black}') +self.assertEqual(pywikibot.bot.color_format('{ans}{black}', ans=42), + '42{black}') + +def test_color_kwargs(self): +"""Test with a color as keyword argument.""" +self.assertRaises(ValueError, + pywikibot.bot.color_format, '{aqua}{black}', aqua=42) + + class FakeSaveBotTestCase(TestCase): """ -- To view, visit https://gerrit.wikimedia.org/r/222907 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib354fb80180b0e421a18474cc67d7ee10cda3745 Gerrit-PatchSet: 1 Gerrit-Project: pywikibot/core Gerrit-Branch: master Gerrit-Owner: XZise ___ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits