def input_choice(self, question, options, default=None, return_shortcut=True, automatic_quit=True, force=False): """ Ask the user and returns a value from the options. Depending on the options setting return_shortcut to False may not be sensible when the option supports multiple values as it'll return an ambiguous index. @param question: The question, without trailing whitespace. @type question: basestring @param options: Iterable of all available options. Each entry contains the full length answer and a shortcut of only one character. Alternatively they may be Option (or subclass) instances or ChoiceException instances which have a full option and shortcut and will be raised if selected. @type options: iterable containing sequences of length 2 or iterable containing Option instances or ChoiceException as well. Singletons of Option and its subclasses are also accepted. @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') 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 default (if it's not None). Otherwise the index of the answer in options. If default is not a shortcut, it'll return -1. @rtype: int (if not return_shortcut), lowercased basestring (otherwise) """ if force and default is None: raise ValueError('With no default option it cannot be forced') if isinstance(options, Option): options = [options] else: # make a copy options = list(options) if len(options) == 0: raise ValueError(u'No options are given.') if automatic_quit: options += [QuitKeyboardInterrupt()] if default: default = default.lower() for i, option in enumerate(options): if not isinstance(option, Option): if len(option) != 2: raise ValueError(u'Option #{0} does not consist of an ' u'option and shortcut.'.format(i)) options[i] = StandardOption(*option) # TODO: Test for uniquity handled = False while not handled: for option in options: if isinstance(option, OutputOption) and option.before_question: option.output() output = Option.formatted(question, options, default) if force: self.output(output + '\n') answer = default else: answer = self.input(output) or default # something entered or default is defined if answer: for index, option in enumerate(options): if option.handled(answer): answer = option.result(answer) handled = option.stop break if isinstance(answer, ChoiceException): raise answer elif not return_shortcut: return index else: return answer
def input_choice(self, question: str, options, default: str = None, return_shortcut: bool = True, automatic_quit: bool = True, force: bool = False): """ Ask the user and returns a value from the options. Depending on the options setting return_shortcut to False may not be sensible when the option supports multiple values as it'll return an ambiguous index. @param question: The question, without trailing whitespace. @param options: Iterable of all available options. Each entry contains the full length answer and a shortcut of only one character. Alternatively they may be Option (or subclass) instances or ChoiceException instances which have a full option and shortcut and will be raised if selected. @type options: iterable containing sequences of length 2 or iterable containing Option instances or ChoiceException as well. Singletons of Option and its subclasses are also accepted. @param default: The default answer if no was entered. None to require an answer. @param return_shortcut: Whether the shortcut or the index in the option should be returned. @param automatic_quit: Adds the option 'Quit' ('q') if True and throws a L{QuitKeyboardInterrupt} if selected. @param force: Automatically use the default @return: If return_shortcut the shortcut of options or the value of default (if it's not None). Otherwise the index of the answer in options. If default is not a shortcut, it'll return -1. @rtype: int (if not return_shortcut), lowercased str (otherwise) """ if force and default is None: raise ValueError('With no default option it cannot be forced') if isinstance(options, Option): options = [options] else: # make a copy options = list(options) if not options: raise ValueError('No options are given.') if automatic_quit: options += [QuitKeyboardInterrupt()] if default: default = default.lower() for i, option in enumerate(options): if not isinstance(option, Option): if len(option) != 2: raise ValueError('Option #{0} does not consist of an ' 'option and shortcut.'.format(i)) options[i] = StandardOption(*option) # TODO: Test for uniquity handled = False while not handled: for option in options: if isinstance(option, OutputOption) and option.before_question: option.output() output = Option.formatted(question, options, default) if force: self.output(output + '\n') answer = default else: answer = self.input(output) or default # something entered or default is defined if answer: for index, option in enumerate(options): if option.handled(answer): answer = option.result(answer) handled = option.stop break if isinstance(answer, ChoiceException): raise answer if not return_shortcut: return index return answer
def input_choice(self, question: str, options: Union[Iterable[Union[Tuple[ str, str], 'pywikibot.bot_choice.Option']], 'pywikibot.bot_choice.Option'], default: Optional[str] = None, return_shortcut: bool = True, automatic_quit: bool = True, force: bool = False) -> Any: """ Ask the user and returns a value from the options. Depending on the options setting return_shortcut to False may not be sensible when the option supports multiple values as it'll return an ambiguous index. :param question: The question, without trailing whitespace. :param options: Iterable of all available options. Each entry contains the full length answer and a shortcut of only one character. Alternatively they may be Option (or subclass) instances or ChoiceException instances which have a full option and shortcut and will be raised if selected. :param default: The default answer if no was entered. None to require an answer. :param return_shortcut: Whether the shortcut or the index in the option should be returned. :param automatic_quit: Adds the option 'Quit' ('q') if True and throws a :py:obj:`QuitKeyboardInterrupt` if selected. :param force: Automatically use the default :return: If return_shortcut the shortcut of options or the value of default (if it's not None). Otherwise the index of the answer in options. If default is not a shortcut, it'll return -1. """ def output_option(option, before_question): """Print an OutputOption before or after question.""" if isinstance(option, OutputOption) \ and option.before_question is before_question: self.stream_output(option.out + '\n') if force and default is None: raise ValueError('With no default option it cannot be forced') if isinstance(options, Option): options = [options] else: # make a copy options = list(options) if not options: raise ValueError('No options are given.') if automatic_quit: options += [QuitKeyboardInterrupt()] if default: default = default.lower() for i, option in enumerate(options): if not isinstance(option, Option): if len(option) != 2: raise ValueError('Option #{} does not consist of an ' 'option and shortcut.'.format(i)) options[i] = StandardOption(*option) # TODO: Test for uniquity handled = False # lock stream output with self.lock: while not handled: for option in options: output_option(option, before_question=True) output = Option.formatted(question, options, default) if force: self.stream_output(output + '\n') answer = default else: answer = self.input(output) or default # something entered or default is defined if answer: for index, option in enumerate(options): if option.handled(answer): answer = option.result(answer) output_option(option, before_question=False) handled = option.stop break if isinstance(answer, ChoiceException): raise answer if not return_shortcut: return index return answer