[MediaWiki-commits] [Gerrit] [FEAT] color_format to ignore valid colors - change (pywikibot/core)

2015-09-18 Thread jenkins-bot (Code Review)
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)

2015-07-05 Thread XZise (Code Review)
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