jenkins-bot has submitted this change and it was merged.

Change subject: [FEAT] input_choice: Support exceptions as options
......................................................................


[FEAT] input_choice: Support exceptions as options

Each option can now be an exception (subclassing ChoiceException) and it'll
automatically raise it when selected. The QuitKeyboardInterrupt does subclass
it and is already integrated into it.

Moved the QuitKeyboardInterrupt into
pywikibot.userinterfaces.terminal_interface_base and it is aliased in the
pywikibot.bot module.

This removes the ability to set the automatic_quit parameter to an int
(pywikibot.bot doesn't even document this feature) as the option can be simply
a ChoiceException or QuitKeyboardInterrupt.

Change-Id: I2ebb7a2839577b721a8a73d772e48c5b2fcce486
---
M pywikibot/__init__.py
M pywikibot/bot.py
M pywikibot/userinterfaces/terminal_interface.py
M pywikibot/userinterfaces/terminal_interface_base.py
M scripts/catall.py
5 files changed, 60 insertions(+), 32 deletions(-)

Approvals:
  John Vandenberg: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index bd05c51..266a054 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -33,7 +33,7 @@
 from pywikibot.bot import (
     output, warning, error, critical, debug, stdout, exception,
     input, input_choice, input_yn, inputChoice, handle_args, showHelp, ui, log,
-    calledModuleName, Bot, CurrentPageBot, WikidataBot, QuitKeyboardInterrupt,
+    calledModuleName, Bot, CurrentPageBot, WikidataBot,
     # the following are flagged as deprecated on usage
     handleArgs,
 )
@@ -757,3 +757,7 @@
     'UserActionRefuse', pywikibot.exceptions._EmailUserError,
     warning_message='UserActionRefuse is deprecated; '
                     'use UserRightsError and/or NotEmailableError')
+wrapper._add_deprecated_attr(
+    'QuitKeyboardInterrupt', pywikibot.bot.QuitKeyboardInterrupt,
+    warning_message='pywikibot.QuitKeyboardInterrupt is deprecated; '
+                    'use pywikibot.bot.QuitKeyboardInterrupt instead')
diff --git a/pywikibot/bot.py b/pywikibot/bot.py
index ca0afba..b58351d 100644
--- a/pywikibot/bot.py
+++ b/pywikibot/bot.py
@@ -52,9 +52,12 @@
 # search for user interface module in the 'userinterfaces' subdirectory
 uiModule = __import__("pywikibot.userinterfaces.%s_interface"
                       % config.userinterface,
-                      fromlist=['UI'])
+                      fromlist=['UI', 'ChoiceException', 
'QuitKeyboardInterrupt'])
 ui = uiModule.UI()
 pywikibot.argvu = ui.argvu()
+
+ChoiceException = uiModule.ChoiceException
+QuitKeyboardInterrupt = uiModule.QuitKeyboardInterrupt
 
 
 # It's not possible to use pywikibot.exceptions.PageRelatedError as that is
@@ -585,7 +588,8 @@
     @type question: basestring
     @param answers: The valid answers each containing a full length answer and
         a shortcut. Each value must be unique.
-    @type answers: Iterable containing an iterable of length two
+    @type answers: iterable containing a sequence of length two or instances of
+        ChoiceException
     @param default: The result if no answer was entered. It must not be in the
         valid answers and can be disabled by setting it to None. If it should
         be linked with the valid answers it must be its shortcut.
@@ -594,7 +598,7 @@
         returned.
     @type return_shortcut: bool
     @param automatic_quit: Adds the option 'Quit' ('q') and throw a
-            L{QuitKeyboardInterrupt} if selected.
+        L{QuitKeyboardInterrupt} if selected.
     @type automatic_quit: bool
     @param force: Automatically use the default
     @type force: bool
@@ -1132,11 +1136,6 @@
     from pywikibot import i18n
     webbrowser.open(page.full_url())
     i18n.input('pywikibot-enter-finished-browser')
-
-
-class QuitKeyboardInterrupt(KeyboardInterrupt):
-
-    """The user has cancelled processing at a prompt."""
 
 
 class BaseBot(object):
diff --git a/pywikibot/userinterfaces/terminal_interface.py 
b/pywikibot/userinterfaces/terminal_interface.py
index 9a5fbf1..768b5e8 100644
--- a/pywikibot/userinterfaces/terminal_interface.py
+++ b/pywikibot/userinterfaces/terminal_interface.py
@@ -20,4 +20,10 @@
 else:
     from .terminal_interface_unix import UnixUI as UI
 
-__all__ = ('UI',)
+from pywikibot.userinterfaces.terminal_interface_base import (
+    ChoiceException, QuitKeyboardInterrupt,
+)
+
+__all__ = (
+    'UI', 'ChoiceException', 'QuitKeyboardInterrupt',
+)
diff --git a/pywikibot/userinterfaces/terminal_interface_base.py 
b/pywikibot/userinterfaces/terminal_interface_base.py
index 2ce3c5d..fa69a1f 100755
--- a/pywikibot/userinterfaces/terminal_interface_base.py
+++ b/pywikibot/userinterfaces/terminal_interface_base.py
@@ -46,6 +46,25 @@
 colorTagR = re.compile('\03{(?P<name>%s)}' % '|'.join(colors))
 
 
+class ChoiceException(Exception):
+
+    """A choice for input_choice which result in this exception."""
+
+    def __init__(self, option, shortcut):
+        """Constructor using the given option and shortcut in input_choice."""
+        self.option = option
+        self.shortcut = shortcut
+
+
+class QuitKeyboardInterrupt(ChoiceException, KeyboardInterrupt):
+
+    """The user has cancelled processing at a prompt."""
+
+    def __init__(self):
+        """Constructor using the 'quit' ('q') in input_choice."""
+        super(QuitKeyboardInterrupt, self).__init__('quit', 'q')
+
+
 class UI:
 
     """Base for terminal user interfaces."""
@@ -258,7 +277,7 @@
             else:
                 text = self._raw_input()
         except KeyboardInterrupt:
-            raise pywikibot.QuitKeyboardInterrupt()
+            raise QuitKeyboardInterrupt()
         if PY2:
             text = text.decode(self.encoding)
         return text
@@ -272,19 +291,20 @@
         @type question: basestring
         @param options: All available options. Each entry contains the full
             length answer and a shortcut of only one character. The shortcut
-            must not appear in the answer.
-        @type options: iterable containing iterables of length 2
+            must not appear in the answer. Alternatively they may be a
+            ChoiceException (or subclass) instance which has a full option and
+            shortcut. It will raise that exception when selected.
+        @type options: iterable containing sequences of length 2 or
+            ChoiceException
         @param default: The default answer if no was entered. None to require
             an answer.
         @type default: basestring
         @param return_shortcut: Whether the shortcut or the index in the option
             should be returned.
         @type return_shortcut: bool
-        @param automatic_quit: Adds the option 'Quit' ('q') and throw a
-            L{QuitKeyboardInterrupt} if selected. If it's an integer it
-            doesn't add the option but throw the exception when the option was
-            selected.
-        @type automatic_quit: bool or int
+        @param automatic_quit: Adds the option 'Quit' ('q') if True and throws 
a
+            L{QuitKeyboardInterrupt} if selected.
+        @type automatic_quit: bool
         @param force: Automatically use the default
         @type force: bool
         @return: If return_shortcut the shortcut of options or the value of
@@ -295,23 +315,21 @@
         options = list(options)
         if len(options) == 0:
             raise ValueError(u'No options are given.')
-        if automatic_quit is True:
-            options += [('Quit', 'q')]
-            quit_index = len(options) - 1
-        elif automatic_quit is not False:
-            quit_index = automatic_quit
-        else:
-            quit_index = None
+        if automatic_quit:
+            options += [QuitKeyboardInterrupt()]
         if default:
             default = default.lower()
         valid = {}
         default_index = -1
         formatted_options = []
         for i, option in enumerate(options):
-            if len(option) != 2:
-                raise ValueError(u'Option #{0} does not consist of an option '
-                                 u'and shortcut.'.format(i))
-            option, shortcut = option
+            if isinstance(option, ChoiceException):
+                option, shortcut = option.option, option.shortcut
+            else:
+                if len(option) != 2:
+                    raise ValueError('Option #{0} does not consist of an '
+                                     'option and shortcut.'.format(i))
+                option, shortcut = option
             if option.lower() in valid:
                 raise ValueError(
                     u'Multiple identical options ({0}).'.format(option))
@@ -342,8 +360,8 @@
                 answer = default_index
             else:
                 answer = valid.get(answer.lower(), None)
-        if quit_index == answer:
-            raise pywikibot.QuitKeyboardInterrupt()
+        if isinstance(options[answer], ChoiceException):
+            raise options[answer]
         elif not return_shortcut:
             return answer
         elif answer < 0:
diff --git a/scripts/catall.py b/scripts/catall.py
index 29bb9a5..a45eb28 100755
--- a/scripts/catall.py
+++ b/scripts/catall.py
@@ -30,6 +30,7 @@
 
 import pywikibot
 from pywikibot import i18n, textlib
+from pywikibot.bot import QuitKeyboardInterrupt
 
 
 def choosecats(pagetext):
@@ -61,7 +62,7 @@
             chosen = None
             done = True
         elif choice == "q":
-            raise pywikibot.QuitKeyboardInterrupt
+            raise QuitKeyboardInterrupt
         else:
             chosen.append(choice)
     return chosen

-- 
To view, visit https://gerrit.wikimedia.org/r/219338
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I2ebb7a2839577b721a8a73d772e48c5b2fcce486
Gerrit-PatchSet: 4
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: XZise <[email protected]>
Gerrit-Reviewer: John Vandenberg <[email protected]>
Gerrit-Reviewer: Ladsgroup <[email protected]>
Gerrit-Reviewer: Merlijn van Deen <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
Pywikibot-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/pywikibot-commits

Reply via email to