jenkins-bot has submitted this change and it was merged.
Change subject: [FIX] editor: Close temporary file handle
......................................................................
[FIX] editor: Close temporary file handle
When using `mkstemp` the file handle must be closed before removing the file.
This was first fixed with 3a4d1844 but the `editor` module also uses `mkstemp`
and is not closing the handle.
Change-Id: I773aff3000fa26b04dcc9b5151fe11a726c0247c
---
M pywikibot/editor.py
1 file changed, 3 insertions(+), 1 deletion(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/editor.py b/pywikibot/editor.py
index 4ccf779..bef3119 100644
--- a/pywikibot/editor.py
+++ b/pywikibot/editor.py
@@ -95,7 +95,8 @@
@rtype: unicode or None
"""
if config.editor:
- tempFilename = '%s.%s' % (tempfile.mkstemp()[1],
+ handle, tempFilename = tempfile.mkstemp()
+ tempFilename = '%s.%s' % (tempFilename,
config.editor_filename_extension)
try:
with codecs.open(tempFilename, 'w',
@@ -113,6 +114,7 @@
newcontent = temp_file.read()
return newcontent
finally:
+ os.close(handle)
os.unlink(tempFilename)
if isinstance(gui, ImportError):
--
To view, visit https://gerrit.wikimedia.org/r/239561
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I773aff3000fa26b04dcc9b5151fe11a726c0247c
Gerrit-PatchSet: 1
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot <>
jenkins-bot has submitted this change and it was merged.
Change subject: Move setting of prop=proofread in Request._add_defaults()
......................................................................
Move setting of prop=proofread in Request._add_defaults()
Convert to a more general approach instead of being specific for
a particular site method.
Avoid use of req._params[key].append()
Removed comment 'TODO: Bug T91912' as bug as been resolved upstream.
Change-Id: I22650d603bc8427b5445a43daafe3717b81472fc
---
M pywikibot/data/api.py
M pywikibot/site.py
2 files changed, 7 insertions(+), 12 deletions(-)
Approvals:
XZise: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/data/api.py b/pywikibot/data/api.py
index b66fa65..e5f1752 100644
--- a/pywikibot/data/api.py
+++ b/pywikibot/data/api.py
@@ -1667,8 +1667,8 @@
if self.action == 'query':
meta = self._params.get("meta", [])
if "userinfo" not in meta:
- meta.append("userinfo")
- self._params["meta"] = meta
+ meta = set(meta + ['userinfo'])
+ self._params['meta'] = list(meta)
uiprop = self._params.get("uiprop", [])
uiprop = set(uiprop + ["blockinfo", "hasmsg"])
self._params["uiprop"] = list(sorted(uiprop))
@@ -1677,6 +1677,10 @@
inprop = self._params.get("inprop", [])
info = set(inprop + ["protection", "talkid", "subjectid"])
self._params["info"] = list(info)
+ if 'prop' in self._params:
+ if self.site.has_extension('ProofreadPage'):
+ prop = set(self._params['prop'] + ['proofread'])
+ self._params['prop'] = list(prop)
# When neither 'continue' nor 'rawcontinue' is present and the
# version number is at least 1.25wmf5 we add a dummy rawcontinue
# parameter. Querying siteinfo is save as it adds 'continue'.
@@ -2839,12 +2843,6 @@
parameters['generator'] = generator
QueryGenerator.__init__(self, **kwargs)
self.resultkey = "pages" # element to look for in result
-
- # TODO: Bug T91912 when using step > 50 with proofread, with queries
- # returning Pages from Page ns.
- if self.site.has_extension('ProofreadPage'):
- self.request['prop'].append('proofread')
-
self.props = self.request['prop']
def result(self, pagedata):
diff --git a/pywikibot/site.py b/pywikibot/site.py
index 9aaceed..a4d6026 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -3657,10 +3657,7 @@
raise ValueError(
"loadrevisions: endid > startid with rvdir=False")
- if self.has_extension('ProofreadPage'):
- rvargs = {'type_arg': 'info|revisions|proofread'}
- else:
- rvargs = {'type_arg': 'info|revisions'}
+ rvargs = {'type_arg': 'info|revisions'}
if getText:
rvargs[u"rvprop"] = u"ids|flags|timestamp|user|comment|content|sha1"
--
To view, visit https://gerrit.wikimedia.org/r/216127
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I22650d603bc8427b5445a43daafe3717b81472fc
Gerrit-PatchSet: 8
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Mpaa <mpaa.wiki(a)gmail.com>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Mpaa <mpaa.wiki(a)gmail.com>
Gerrit-Reviewer: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: jenkins-bot <>
Build Update for wikimedia/pywikibot-core
-------------------------------------
Build: #2869
Status: Errored
Duration: 27 minutes and 50 seconds
Commit: 3a4d184 (master)
Author: xqt
Message: [FIX] Close file handle before removing a tempory file.
mkstemp() returns a tuple containing OS-level file handle to an open file
and the absolute pathname of that file. The file might be reopended several
times and closed by with-statement. But the first file handle opened
by mkstemp() keeps still open. It must be closed explicitly.
Bug: T113127
Change-Id: Icf104ebee21448b405c9e4671e112d68cda68597
View the changeset: https://github.com/wikimedia/pywikibot-core/compare/7634a0515714...3a4d1844…
View the full build log and details: https://travis-ci.org/wikimedia/pywikibot-core/builds/81155114
--
You can configure recipients for build notifications in your .travis.yml file. See http://docs.travis-ci.com/user/notifications
jenkins-bot has submitted this change and it was merged.
Change subject: [FIX] Close file handle before removing a tempory file.
......................................................................
[FIX] Close file handle before removing a tempory file.
mkstemp() returns a tuple containing OS-level file handle to an open file
and the absolute pathname of that file. The file might be reopended several
times and closed by with-statement. But the first file handle opened
by mkstemp() keeps still open. It must be closed explicitly.
Bug: T113127
Change-Id: Icf104ebee21448b405c9e4671e112d68cda68597
---
M tests/tools_tests.py
1 file changed, 2 insertions(+), 1 deletion(-)
Approvals:
XZise: Looks good to me, approved
jenkins-bot: Verified
diff --git a/tests/tools_tests.py b/tests/tools_tests.py
index 4d98d49..2c63736 100644
--- a/tests/tools_tests.py
+++ b/tests/tools_tests.py
@@ -157,7 +157,7 @@
def _write_content(self, suffix):
try:
- fn = tempfile.mkstemp(suffix)[1]
+ fh, fn = tempfile.mkstemp(suffix)
with tools.open_archive(fn, 'wb') as f:
f.write(self.original_content)
with tools.open_archive(fn, 'rb') as f:
@@ -165,6 +165,7 @@
with open(fn, 'rb') as f:
return f.read()
finally:
+ os.close(fh)
os.remove(fn)
def test_invalid_modes(self):
--
To view, visit https://gerrit.wikimedia.org/r/239556
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Icf104ebee21448b405c9e4671e112d68cda68597
Gerrit-PatchSet: 1
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: jenkins-bot <>
jenkins-bot has submitted this change and it was merged.
Change subject: [FIX] config: Inverted PY2 logic
......................................................................
[FIX] config: Inverted PY2 logic
In 97f69a60, `PY2` was redefined in the `config2` module instead of using
`tools`' implementation. This adds an error as the logic was actually detecting
//non-PY2//. To minimize the redundancy it's now using `tools`' implementation.
Change-Id: Id467fd3d0c176a70d9192639e694fd3b4fd2129a
---
M pywikibot/config2.py
1 file changed, 1 insertion(+), 1 deletion(-)
Approvals:
John Vandenberg: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/config2.py b/pywikibot/config2.py
index b383cc3..c5ad2c1 100644
--- a/pywikibot/config2.py
+++ b/pywikibot/config2.py
@@ -54,9 +54,9 @@
from pywikibot import __url__
from pywikibot.logging import error, output, warning
+from pywikibot.tools import PY2
OSWIN32 = (sys.platform == 'win32')
-PY2 = (sys.version_info[0] > 2)
if OSWIN32:
if not PY2:
--
To view, visit https://gerrit.wikimedia.org/r/239550
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Id467fd3d0c176a70d9192639e694fd3b4fd2129a
Gerrit-PatchSet: 1
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: jenkins-bot <>
jenkins-bot has submitted this change and it was merged.
Change subject: Define PY2 and OSWIN32 once in config module
......................................................................
Define PY2 and OSWIN32 once in config module
Move imports to the top and re-order the imports
Change-Id: I920beb91a2a2e6ea690fbc13d2b11e0b22af490c
---
M pywikibot/config2.py
1 file changed, 18 insertions(+), 14 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/config2.py b/pywikibot/config2.py
index ebc2cc7..b383cc3 100644
--- a/pywikibot/config2.py
+++ b/pywikibot/config2.py
@@ -44,20 +44,26 @@
import collections
import os
+import platform
+import re
import stat
import sys
-import re
+import types
from warnings import warn
-if sys.platform == 'win32':
- if sys.version_info[0] > 2:
+from pywikibot import __url__
+from pywikibot.logging import error, output, warning
+
+OSWIN32 = (sys.platform == 'win32')
+PY2 = (sys.version_info[0] > 2)
+
+if OSWIN32:
+ if not PY2:
import winreg
else:
import _winreg as winreg
-from pywikibot import __url__
-from pywikibot.logging import error, output, warning
# This frozen set should contain all imported modules/variables, so it must
# occur directly after the imports. At that point globals() only contains the
@@ -287,8 +293,7 @@
else:
base_dir_cand = []
home = os.path.expanduser("~")
- if sys.platform == 'win32':
- import platform
+ if OSWIN32:
win_version = int(platform.version()[0])
if win_version == 5:
sub_dir = ["Application Data"]
@@ -374,7 +379,7 @@
# This default code should work fine, so you don't have to think about it.
# TODO: consider getting rid of this config variable.
try:
- if sys.version_info[0] > 2 or not sys.stdout.encoding:
+ if not PY2 or not sys.stdout.encoding:
console_encoding = sys.stdout.encoding
else:
console_encoding = sys.stdout.encoding.decode('ascii')
@@ -935,8 +940,8 @@
_filestatus = os.stat(_filename)
_filemode = _filestatus[0]
_fileuid = _filestatus[4]
- if sys.platform == 'win32' or _fileuid in [os.getuid(), 0]:
- if sys.platform == 'win32' or _filemode & 0o02 == 0:
+ if OSWIN32 or _fileuid in [os.getuid(), 0]:
+ if OSWIN32 or _filemode & 0o02 == 0:
with open(_filename, 'rb') as f:
exec(compile(f.read(), _filename, 'exec'), _uc)
else:
@@ -1032,7 +1037,7 @@
# Fix up transliteration_target
if transliteration_target == 'not set':
- if sys.platform == 'win32':
+ if OSWIN32:
transliteration_target = console_encoding
warning(
'Running on Windows and transliteration_target is not set.\n'
@@ -1043,10 +1048,10 @@
transliteration_target = None
-if sys.platform == 'win32' and editor is None:
+if OSWIN32 and editor is None:
editor = _detect_win32_editor()
-if sys.platform == 'win32' and editor:
+if OSWIN32 and editor:
# single character string literals from
# https://docs.python.org/2/reference/lexical_analysis.html#string-literals
# encode('unicode-escape') also changes Unicode characters
@@ -1080,7 +1085,6 @@
# When called as main program, list all configuration variables
#
if __name__ == "__main__":
- import types
_all = 1
for _arg in sys.argv[1:]:
if _arg == "modified":
--
To view, visit https://gerrit.wikimedia.org/r/239536
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I920beb91a2a2e6ea690fbc13d2b11e0b22af490c
Gerrit-PatchSet: 1
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot <>
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 '
- '\03{{{{lightpurple}}}}{0}\03{{{{default}}}}?').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)))
+ return super(_ColorFormatter, self).vformat(format_string, args,
+ kwargs)
+
+
+def color_format(text, *args, **kwargs):
+ r"""
+ Do C{str.format} without having to worry about colors.
+
+ It is automatically adding \03 in front of color fields so it's
+ unnecessary to add them manually. Any other \03 in the text is disallowed.
+ """
+ return _ColorFormatter().format(text, *args, **kwargs)
diff --git a/tests/tools_formatter_tests.py b/tests/tools_formatter_tests.py
index 74d9768..a441e35 100644
--- a/tests/tools_formatter_tests.py
+++ b/tests/tools_formatter_tests.py
@@ -31,6 +31,50 @@
self.assertEqual(outputter.format_list(), '\nfoo\nbar\n')
+class TestColorFormat(TestCase):
+
+ """Test color_format function in bot module."""
+
+ net = False
+
+ def test_no_colors(self):
+ """Test without colors in template string."""
+ self.assertEqual(formatter.color_format('42'), '42')
+ self.assertEqual(formatter.color_format('{0}', 42), '42')
+ self.assertEqual(formatter.color_format('{ans}', ans=42), '42')
+
+ def test_colors(self):
+ """Test with colors in template string."""
+ self.assertEqual(formatter.color_format('{0}{black}', 42),
+ '42\03{black}')
+ self.assertEqual(formatter.color_format('{ans}{black}', ans=42),
+ '42\03{black}')
+ self.assertRaisesRegex(
+ ValueError, r'.*conversion.*', formatter.color_format,
+ '{0}{black!r}', 42)
+ self.assertRaisesRegex(
+ ValueError, r'.*format spec.*', formatter.color_format,
+ '{0}{black:03}', 42)
+
+ def test_marker(self):
+ r"""Test that the \03 marker is only allowed in front of colors."""
+ self.assertEqual(formatter.color_format('{0}\03{black}', 42),
+ '42\03{black}')
+ # literal before a normal field
+ self.assertRaisesRegex(
+ ValueError, r'.*\\03', formatter.color_format,
+ '\03{0}{black}', 42)
+ # literal before a color field
+ self.assertRaisesRegex(
+ ValueError, r'.*\\03', formatter.color_format,
+ '{0}\03before{black}', 42)
+
+ def test_color_kwargs(self):
+ """Test with a color as keyword argument."""
+ self.assertRaises(ValueError,
+ formatter.color_format, '{aqua}{black}', aqua=42)
+
+
if __name__ == '__main__':
try:
unittest.main()
--
To view, visit https://gerrit.wikimedia.org/r/222907
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ib354fb80180b0e421a18474cc67d7ee10cda3745
Gerrit-PatchSet: 5
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Mpaa <mpaa.wiki(a)gmail.com>
Gerrit-Reviewer: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: jenkins-bot <>
jenkins-bot has submitted this change and it was merged.
Change subject: [FIX/IMPROV] Add option class to output the list
......................................................................
[FIX/IMPROV] Add option class to output the list
The alternatives output by `listAlternatives` are zero-based while the option
is one-based since 9c590fed. This adds the option class `OutputProxyOption`
which just calls `output` of the class used for it.
One class which can be used is `SequenceOutputter` which can be used together
with `ListOption` and does just create a string listing the contents of a list.
That class is creating a one-based string which is output. It also has a
flexible indentation depending on the number of alternatives.
Using the separate `SequenceOutputter` class has the advantage that it's
possible to create such strings without being tied into using an option.
Bug: T107272
Change-Id: If843cb0af86292b6a6ab426662d4831503ea47b5
---
M pywikibot/bot.py
M pywikibot/bot_choice.py
A pywikibot/tools/formatter.py
M scripts/solve_disambiguation.py
A tests/tools_formatter_tests.py
5 files changed, 122 insertions(+), 21 deletions(-)
Approvals:
John Vandenberg: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/bot.py b/pywikibot/bot.py
index 9b15a39..c0a119c 100644
--- a/pywikibot/bot.py
+++ b/pywikibot/bot.py
@@ -86,7 +86,7 @@
from pywikibot import version
from pywikibot.bot_choice import ( # noqa: unused imports
Option, StandardOption, NestedOption, IntegerOption, ContextOption,
- ListOption, HighlightContextOption,
+ ListOption, OutputProxyOption, HighlightContextOption,
ChoiceException, QuitKeyboardInterrupt,
)
from pywikibot.logging import CRITICAL, ERROR, INFO, WARNING # noqa: unused
@@ -360,6 +360,7 @@
add_init_routine(init_handlers)
+
# User input functions
diff --git a/pywikibot/bot_choice.py b/pywikibot/bot_choice.py
index 5a56915..95e2144 100755
--- a/pywikibot/bot_choice.py
+++ b/pywikibot/bot_choice.py
@@ -125,6 +125,20 @@
self.option.lower() == value.lower())
+class OutputProxyOption(OutputOption, StandardOption):
+
+ """An option which calls output of the given output class."""
+
+ def __init__(self, option, shortcut, output):
+ """Create a new option for the given sequence."""
+ super(OutputProxyOption, self).__init__(option, shortcut)
+ self._outputter = output
+
+ def output(self):
+ """Output the contents."""
+ self._outputter.output()
+
+
class NestedOption(OutputOption, StandardOption):
"""
diff --git a/pywikibot/tools/formatter.py b/pywikibot/tools/formatter.py
new file mode 100644
index 0000000..d2f15e2
--- /dev/null
+++ b/pywikibot/tools/formatter.py
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+"""Module containing various formatting related utilities."""
+#
+# (C) Pywikibot team, 2015
+#
+# Distributed under the terms of the MIT license.
+#
+from __future__ import absolute_import, unicode_literals
+
+__version__ = '$Id$'
+
+import math
+
+from pywikibot.logging import output
+
+
+class SequenceOutputter(object):
+
+ """
+ A class formatting a list of items.
+
+ It is possible to customize the appearance by changing C{format_string}
+ which is used by C{str.format} with C{index}, C{width} and C{item}. Each
+ line is joined by the separator and the complete text is surrounded by the
+ prefix and the suffix. All three are by default a new line. The index starts
+ at 1 and for the width it's using the width of the sequence's length written
+ as a decimal number. So a length of 100 will result in a with of 3 and a
+ length of 99 in a width of 2.
+
+ It is iterating over C{self.sequence} to generate the text. That sequence
+ can be any iterator but the result is better when it has an order.
+ """
+
+ format_string = ' {index:>{width}} - {item}'
+ separator = '\n'
+ prefix = '\n'
+ suffix = '\n'
+
+ def __init__(self, sequence):
+ """Create a new instance with a reference to the sequence."""
+ super(SequenceOutputter, self).__init__()
+ self.sequence = sequence
+
+ def format_list(self):
+ """Create the text with one item on each line."""
+ if self.sequence:
+ # Width is only defined when the length is greater 0
+ width = int(math.log10(len(self.sequence))) + 1
+ content = self.separator.join(
+ self.format_string.format(index=i, item=item, width=width)
+ for i, item in enumerate(self.sequence, start=1))
+ else:
+ content = ''
+ return self.prefix + content + self.suffix
+
+ def output(self):
+ """Output the text of the current sequence."""
+ output(self.format_list())
diff --git a/scripts/solve_disambiguation.py b/scripts/solve_disambiguation.py
index 2e71f1a..cca88ab 100755
--- a/scripts/solve_disambiguation.py
+++ b/scripts/solve_disambiguation.py
@@ -91,8 +91,9 @@
from pywikibot import pagegenerators, config, i18n
from pywikibot.bot import (
Bot, QuitKeyboardInterrupt,
- StandardOption, HighlightContextOption, ListOption,
+ StandardOption, HighlightContextOption, ListOption, OutputProxyOption,
)
+from pywikibot.tools.formatter import SequenceOutputter
# Disambiguation Needed template
dn_template = {
@@ -452,28 +453,14 @@
pass
-class ListAlternativesOption(StandardOption):
-
- """List the alternatives."""
-
- def __init__(self, option, shortcut, bot):
- """Constructor."""
- super(ListAlternativesOption, self).__init__(option, shortcut, False)
- self._bot = bot
-
- def result(self, value):
- """List the alternatives."""
- self._bot.listAlternatives()
-
-
-class AddAlternativeOption(ListAlternativesOption):
+class AddAlternativeOption(OutputProxyOption):
"""Add a new alternative."""
def result(self, value):
"""Add the alternative and then list them."""
newAlternative = pywikibot.input(u'New alternative:')
- self._bot.alternatives.append(newAlternative)
+ self._outputter.sequence.append(newAlternative)
super(AddAlternativeOption, self).result(value)
@@ -763,8 +750,11 @@
if not edited:
options += [ShowPageOption('show disambiguation page', 'd',
m.start(), disambPage)]
- options += [ListAlternativesOption('list', 'l', self),
- AddAlternativeOption('add new', 'a', self)]
+ options += [
+ OutputProxyOption('list', 'l',
+ SequenceOutputter(self.alternatives)),
+ AddAlternativeOption('add new', 'a',
+ SequenceOutputter(self.alternatives))]
if edited:
options += [StandardOption('save in this form', 'x')]
@@ -1054,7 +1044,7 @@
self.alternatives.sort(key=lambda x: x.lower())
else:
self.alternatives.sort()
- self.listAlternatives()
+ SequenceOutputter(self.alternatives).output()
gen = ReferringPageGeneratorWithIgnore(disambPage, self.primary,
minimum=self.minimum)
diff --git a/tests/tools_formatter_tests.py b/tests/tools_formatter_tests.py
new file mode 100644
index 0000000..256f2ed
--- /dev/null
+++ b/tests/tools_formatter_tests.py
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+"""Tests for the C{pywikibot.tools.formatter} module."""
+#
+# (C) Pywikibot team, 2015
+#
+# Distributed under the terms of the MIT license.
+#
+from __future__ import unicode_literals
+
+__version__ = '$Id$'
+#
+from pywikibot.tools import formatter
+
+from tests.aspects import unittest, TestCase
+
+
+class TestListOutputter(TestCase):
+
+ """Test ListFormatter class."""
+
+ net = False
+
+ def test_SequenceOutputter(self):
+ """Test format method."""
+ options = ['foo', 'bar']
+ outputter = formatter.SequenceOutputter(options)
+ self.assertEqual(outputter.format_list(), '\n 1 - foo\n 2 - bar\n')
+ outputter.format_string = '({index} {width} {item})'
+ self.assertEqual(outputter.format_list(), '\n(1 1 foo)\n(2 1 bar)\n')
+ outputter.format_string = '{item}'
+ self.assertEqual(outputter.format_list(), '\nfoo\nbar\n')
+
+
+if __name__ == '__main__':
+ try:
+ unittest.main()
+ except SystemExit:
+ pass
--
To view, visit https://gerrit.wikimedia.org/r/227679
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: If843cb0af86292b6a6ab426662d4831503ea47b5
Gerrit-PatchSet: 6
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot <>