jenkins-bot has submitted this change. ( https://gerrit.wikimedia.org/r/c/pywikibot/core/+/696497 )
Change subject: [bugfix] postpone hte cached output implementation ......................................................................
[bugfix] postpone hte cached output implementation
Bug: T282962 Change-Id: I0dc8cee5512840b559c76458c02533d598a93c24 --- M ROADMAP.rst M pywikibot/userinterfaces/terminal_interface_base.py M tests/i18n_tests.py 3 files changed, 61 insertions(+), 93 deletions(-)
Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
diff --git a/ROADMAP.rst b/ROADMAP.rst index eb79753..c39575b 100644 --- a/ROADMAP.rst +++ b/ROADMAP.rst @@ -5,7 +5,6 @@ -------------------------
* Fix iterating of SizedKeyCollection (T282865) -* The cached output functionality from compat relase was re-implemented (T151727, T73646, T74942, T132135, T144698, T196039, T280466) * An abstract base user interface module was added * APISite method pagelanglinks() may skip links with empty titles (T223157) * Fix Page.getDeletedRevision() method which always returned an empty list diff --git a/pywikibot/userinterfaces/terminal_interface_base.py b/pywikibot/userinterfaces/terminal_interface_base.py index 4adcac6..1b12f26 100755 --- a/pywikibot/userinterfaces/terminal_interface_base.py +++ b/pywikibot/userinterfaces/terminal_interface_base.py @@ -13,7 +13,7 @@
import pywikibot from pywikibot import config -from pywikibot.backports import Sequence, SimpleQueue +from pywikibot.backports import Sequence from pywikibot.bot_choice import ( ChoiceException, Option, @@ -22,7 +22,7 @@ StandardOption, ) from pywikibot.logging import INFO, INPUT, STDOUT, VERBOSE, WARNING -from pywikibot.tools import deprecated_args, RLock +from pywikibot.tools import deprecated_args from pywikibot.userinterfaces import transliteration from pywikibot.userinterfaces._interface_base import ABUIC
@@ -77,9 +77,6 @@ self.encoding = config.console_encoding self.transliteration_target = config.transliteration_target
- self.cache = SimpleQueue() - self.lock = RLock() - def init_handlers(self, root_logger, default_stream='stderr'): """Initialize the handlers for user output.
@@ -188,38 +185,12 @@ self.encounter_color(color_stack[-1], target_stream)
def output(self, text, targetStream=None): - """Forward text to cache and flush if output is not locked. - - All input methods locks the output to a stream but collect them - in cache. They will be printed with next unlocked output call or - at termination time. - """ - self.cache_output(text, targetStream=targetStream) - if not self.lock.locked(): - self.flush() - - def flush(self): - """Output cached text.""" - while not self.cache.empty(): - args, kwargs = self.cache.get_nowait() - self.stream_output(*args, **kwargs) - - def cache_output(self, *args, **kwargs): - """Put text to cache. - - *New in version 6.2* - """ - self.cache.put_nowait((args, kwargs)) - - def stream_output(self, text, targetStream=None): """ Output text to a stream.
If a character can't be displayed in the encoding used by the user's terminal, it will be replaced with a question mark or by a transliteration. - - *New in version 6.2* """ if config.transliterate: # Encode our unicode string in the encoding used by the user's @@ -305,26 +276,26 @@ question += end_marker
# lock stream output - with self.lock: - if force: - self.stream_output(question + '\n') + # with self.lock: (T282962) + if force: + self.output(question + '\n') + return default + # sound the terminal bell to notify the user + if config.ring_bell: + sys.stdout.write('\07') + # TODO: make sure this is logged as well + while True: + self.output(question + ' ') + text = self._input_reraise_cntl_c(password) + + if text is None: + continue + + if text: + return text + + if default is not None: return default - # sound the terminal bell to notify the user - if config.ring_bell: - sys.stdout.write('\07') - # TODO: make sure this is logged as well - while True: - self.stream_output(question + ' ') - text = self._input_reraise_cntl_c(password) - - if text is None: - continue - - if text: - return text - - if default is not None: - return default
def _input_reraise_cntl_c(self, password): """Input and decode, and re-raise Control-C.""" @@ -377,7 +348,7 @@ """Print an OutputOption before or after question.""" if isinstance(option, OutputOption) \ and option.before_question is before_question: - self.stream_output(option.out + '\n') + self.output(option.out + '\n')
if force and default is None: raise ValueError('With no default option it cannot be forced') @@ -402,24 +373,24 @@ 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 + # with self.lock: (T282962) + while not handled: + for option in options: + output_option(option, before_question=True) + 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) + output_option(option, before_question=False) + handled = option.stop + break
if isinstance(answer, ChoiceException): raise answer @@ -440,33 +411,31 @@ @return: Return a single Sequence entry. """ # lock stream output - with self.lock: - if not force: - line_template = '{{0: >{}}}: {{1}}'.format( - len(str(len(answers)))) - for i, entry in enumerate(answers, start=1): - self.stream_output(line_template.format(i, entry)) + # with self.lock: (T282962) + if not force: + line_template = '{{0: >{}}}: {{1}}'.format(len(str(len(answers)))) + for i, entry in enumerate(answers, start=1): + self.output(line_template.format(i, entry))
- while True: - choice = self.input(question, default=default, force=force) + while True: + choice = self.input(question, default=default, force=force)
- try: - choice = int(choice) - 1 - except (TypeError, ValueError): - if choice in answers: - return choice - choice = -1 + try: + choice = int(choice) - 1 + except (TypeError, ValueError): + if choice in answers: + return choice + choice = -1
- # User typed choice number - if 0 <= choice < len(answers): - return answers[choice] + # User typed choice number + if 0 <= choice < len(answers): + return answers[choice]
- if force: - raise ValueError( - 'Invalid value "{}" for default during force.' - .format(default)) + if force: + raise ValueError('Invalid value "{}" for default during force.' + .format(default))
- pywikibot.error('Invalid response') + pywikibot.error('Invalid response')
def editText(self, text: str, jumpIndex: Optional[int] = None, highlight: Optional[str] = None): diff --git a/tests/i18n_tests.py b/tests/i18n_tests.py index b80d6fb..74c2be5 100644 --- a/tests/i18n_tests.py +++ b/tests/i18n_tests.py @@ -342,7 +342,7 @@ self.orig_raw_input = bot.ui._raw_input self.orig_output = bot.ui.output bot.ui._raw_input = lambda *args, **kwargs: 'dummy input' - bot.ui.stream_output = self._capture_output + bot.ui.output = self._capture_output self.old_cc_setting = config.cosmetic_changes_mylang_only
def tearDown(self):
pywikibot-commits@lists.wikimedia.org