jenkins-bot has submitted this change. ( 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/656608 )

Change subject: [bugfix] Improvements for input_list_choice()
......................................................................

[bugfix] Improvements for input_list_choice()

- add doc and typing hints to UI.input_list_choice().
- simplify line_template for printing answers Sequence.
- do not print answers Collection if force option is set.
  The default value is already shown.
- Test input result for TypeError which may occur if default is None.
- raise ValueError if force is set and default value is not set
  or default value is invalid; otherwise it would cause an infinite
  loop.
- early return the answer value if it is member of answers Sequence.
- default value of input_list_choice may be an int too
- add Sequence to backports.py for typing hints

Bug: T272237
Change-Id: Icb9ac82264c15d13e0dcff82d63cff71163c5a5b
---
M pywikibot/backports.py
M pywikibot/bot.py
M pywikibot/userinterfaces/terminal_interface_base.py
3 files changed, 39 insertions(+), 28 deletions(-)

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



diff --git a/pywikibot/backports.py b/pywikibot/backports.py
index afe8383..487447a 100644
--- a/pywikibot/backports.py
+++ b/pywikibot/backports.py
@@ -1,6 +1,6 @@
 """This module contains backports to support older Python versions."""
 #
-# (C) Pywikibot team, 2020
+# (C) Pywikibot team, 2020-2021
 #
 # Distributed under the terms of the MIT license.
 #
@@ -23,14 +23,14 @@
     from collections import defaultdict as DefaultDict  # noqa: N812

 if PYTHON_VERSION >= (3, 9):
-    from collections.abc import Iterable
+    from collections.abc import Iterable, Sequence
     Dict = dict
     FrozenSet = frozenset
     List = list
     Set = set
     Tuple = tuple
 else:
-    from typing import Dict, FrozenSet, Iterable, List, Set, Tuple
+    from typing import Dict, FrozenSet, Iterable, List, Set, Sequence, Tuple


 # PEP 616 string methods
diff --git a/pywikibot/bot.py b/pywikibot/bot.py
index 204ed9b..7f514cf 100644
--- a/pywikibot/bot.py
+++ b/pywikibot/bot.py
@@ -102,7 +102,7 @@
 from warnings import warn

 import pywikibot
-from pywikibot.backports import Dict, Iterable, List
+from pywikibot.backports import Dict, Iterable, List, Sequence
 from pywikibot import config2 as config
 from pywikibot import daemonize
 from pywikibot import i18n
@@ -510,15 +510,14 @@
                         automatic_quit=automatic_quit, force=force) == 'y'


-def input_list_choice(question: str, answers,
-                      default: Optional[str] = None,
+def input_list_choice(question: str, answers: Sequence[Any],
+                      default: Union[int, str, None] = None,
                       force: bool = False) -> str:
     """
     Ask the user the question and return one of the valid answers.

     @param question: The question asked without trailing spaces.
     @param answers: The valid answers each containing a full length answer.
-    @type answers: Iterable of str
     @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.
     @param force: Automatically use the default
diff --git a/pywikibot/userinterfaces/terminal_interface_base.py 
b/pywikibot/userinterfaces/terminal_interface_base.py
index bc314f6..2ca2ec8 100755
--- a/pywikibot/userinterfaces/terminal_interface_base.py
+++ b/pywikibot/userinterfaces/terminal_interface_base.py
@@ -1,21 +1,22 @@
 # -*- coding: utf-8 -*-
 """Base for terminal user interfaces."""
 #
-# (C) Pywikibot team, 2003-2020
+# (C) Pywikibot team, 2003-2021
 #
 # Distributed under the terms of the MIT license.
 #
 import getpass
 import logging
-import math
 import re
 import sys
 import threading

-from typing import Optional
+from typing import Any, Optional, Union

 import pywikibot
 from pywikibot import config2 as config
+
+from pywikibot.backports import Sequence
 from pywikibot.bot import VERBOSE, INFO, STDOUT, INPUT, WARNING
 from pywikibot.bot_choice import (ChoiceException, Option, OutputOption,
                                   QuitKeyboardInterrupt, StandardOption)
@@ -380,31 +381,42 @@
             return index
         return answer

-    def input_list_choice(self, question, answers, default=None, force=False):
-        """Ask the user to select one entry from a list of entries."""
-        message = question
-        clist = answers
+    def input_list_choice(self, question: str, answers: Sequence[Any],
+                          default: Union[int, str, None] = None,
+                          force: bool = False) -> Any:
+        """Ask the user to select one entry from a list of entries.

-        line_template = '{{0: >{0}}}: {{1}}'.format(
-            int(math.log10(len(clist)) + 1))
-        for n, i in enumerate(clist):
-            pywikibot.output(line_template.format(n + 1, i))
+        @param question: The question, without trailing whitespace.
+        @param answers: A sequence of options to be choosen.
+        @param default: The default answer if no was entered. None to require
+            an answer.
+        @param force: Automatically use the default.
+        @return: Return a single Sequence entry.
+        """
+        if not force:
+            line_template = '{{0: >{0}}}: {{1}}'.format(len(str(len(answers))))
+            for i, entry in enumerate(answers, start=1):
+                pywikibot.output(line_template.format(i, entry))

         while True:
-            choice = self.input(message, default=default, force=force)
+            choice = self.input(question, default=default, force=force)
+
             try:
                 choice = int(choice) - 1
-            except ValueError:
-                try:
-                    choice = clist.index(choice)
-                except IndexError:
-                    choice = -1
+            except (TypeError, ValueError):
+                if choice in answers:
+                    return choice
+                choice = -1

             # User typed choice number
-            if 0 <= choice < len(clist):
-                return clist[choice]
-            else:
-                pywikibot.error('Invalid response')
+            if 0 <= choice < len(answers):
+                return answers[choice]
+
+            if force:
+                raise ValueError('Invalid value "{}" for default during force.'
+                                 .format(default))
+
+            pywikibot.error('Invalid response')

     def editText(self, text: str, jumpIndex: Optional[int] = None,
                  highlight: Optional[str] = None):

--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/656608
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.wikimedia.org/r/settings

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Icb9ac82264c15d13e0dcff82d63cff71163c5a5b
Gerrit-Change-Number: 656608
Gerrit-PatchSet: 7
Gerrit-Owner: Xqt <[email protected]>
Gerrit-Reviewer: JJMC89 <[email protected]>
Gerrit-Reviewer: Mpaa <[email protected]>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
_______________________________________________
Pywikibot-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/pywikibot-commits

Reply via email to