jenkins-bot submitted this change.

View Change

Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
[bugfix] buffer_interface string representation is unhelpful

Our buffer_interface has an unhelpful string representation because it
subclasses logging.Handler...

>>> import pywikibot.userinterfaces.buffer_interface
>>> import pywikibot.userinterfaces.terminal_interface

>>> buffer_ui = pywikibot.userinterfaces.buffer_interface.UI()
>>> repr(buffer_ui)
'<UI (INFO)>'

>>> unix_ui = pywikibot.userinterfaces.terminal_interface.UI()
>>> str(unix_ui)
'<pywikibot.userinterfaces.terminal_interface_unix.UnixUI object at
0x7fc30076ec40>'

We can simply have a log handler attribute rather than subclass it. Doing so
fixes this.

>>> import pywikibot.userinterfaces.buffer_interface
>>> buffer_ui = pywikibot.userinterfaces.buffer_interface.UI()
>>> repr(buffer_ui)
'<pywikibot.userinterfaces.buffer_interface.UI object at 0x7fcc23ddecd0>'

This drops the get_output() method from the UI class because it's unused and
incompatible with a QueueHandler.

Change-Id: Ia898cb8ebcd9afae9b55baa173eb37853a871e37
---
M pywikibot/userinterfaces/buffer_interface.py
1 file changed, 24 insertions(+), 18 deletions(-)

diff --git a/pywikibot/userinterfaces/buffer_interface.py b/pywikibot/userinterfaces/buffer_interface.py
index 8978304..d4b683e 100755
--- a/pywikibot/userinterfaces/buffer_interface.py
+++ b/pywikibot/userinterfaces/buffer_interface.py
@@ -5,28 +5,32 @@
# Distributed under the terms of the MIT license.
#
import logging
+import queue
from typing import Any, Sequence, Union

from pywikibot import config
from pywikibot.logging import INFO, VERBOSE
from pywikibot.userinterfaces._interface_base import ABUIC

+BAD_BUFFER_TYPE = 'BUG: bufffer can only contain logs and strings, had {}'

-class UI(ABUIC, logging.Handler):
+
+class UI(ABUIC):

"""Collects output into an unseen buffer."""

def __init__(self):
"""Initialize the UI."""
super().__init__()
- self.setLevel(VERBOSE if config.verbose_output else INFO)
- self.setFormatter(logging.Formatter(fmt='%(message)s%(newline)s'))

- self._output = []
+ self._buffer = queue.Queue()
+
+ self.log_handler = logging.handlers.QueueHandler(self._buffer)
+ self.log_handler.setLevel(VERBOSE if config.verbose_output else INFO)

def init_handlers(self, root_logger, *args, **kwargs):
"""Initialize the handlers for user output."""
- root_logger.addHandler(self)
+ root_logger.addHandler(self.log_handler)

def input(self, question: str, password: bool = False,
default: str = '', force: bool = False) -> str:
@@ -47,22 +51,24 @@

def output(self, text, *args, **kwargs) -> None:
"""Output text that would usually go to a stream."""
- self._output.append(text)
-
- def emit(self, record: logging.LogRecord) -> None:
- """Logger output."""
- self.output(record.getMessage())
-
- def get_output(self):
- """Provides any output we've buffered."""
- return list(self._output)
+ self._buffer.put(text)

def pop_output(self):
"""Provide and clear any buffered output."""
- buffered_output = self.get_output()
- self.clear()
- return buffered_output
+ output = []
+
+ while not self._buffer.empty():
+ record = self._buffer.get_nowait()
+
+ if isinstance(record, str):
+ output.append(record)
+ elif isinstance(record, logging.LogRecord):
+ output.append(record.getMessage())
+ else:
+ raise ValueError(BAD_BUFFER_TYPE.format(type(record).__name__))
+
+ return output

def clear(self):
"""Removes any buffered output."""
- self._output.clear()
+ self.pop_output()

To view, visit change 703917. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Ia898cb8ebcd9afae9b55baa173eb37853a871e37
Gerrit-Change-Number: 703917
Gerrit-PatchSet: 2
Gerrit-Owner: Damian <atagar1@gmail.com>
Gerrit-Reviewer: Damian <atagar1@gmail.com>
Gerrit-Reviewer: Xqt <info@gno.de>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged