[python-meh] Allow a change of the I/O functions
Vratislav Podzimek
vpodzime at redhat.com
Tue Mar 26 13:56:59 UTC 2013
This is needed for Anaconda's text mode that has its own raw_input
function that has to be used also by python-meh. And it will come
handy when writing automated tests for python-meh's text interface.
Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
---
meh/ui/text.py | 79 ++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 63 insertions(+), 16 deletions(-)
diff --git a/meh/ui/text.py b/meh/ui/text.py
index 1b1e297..9bed60a 100644
--- a/meh/ui/text.py
+++ b/meh/ui/text.py
@@ -17,6 +17,8 @@
# Author(s): Chris Lumens <clumens at redhat.com>
# Vratislav Podzimek <vpodzime at redhat.com>
#
+from __future__ import print_function
+
from meh import *
from meh.ui import *
import report
@@ -28,10 +30,40 @@ import os
import gettext
_ = lambda x: gettext.ldgettext("python-meh", x)
+
+class IOHandler(object):
+ """
+ Class that provides methods for input and output. Its instance is expected
+ to be passed to objects performing some I/O operations.
+
+ """
+
+ def __init__(self, in_func=raw_input, out_func=print):
+ """
+ Constructor for the IOhandler class. Arguments can be used to override
+ default I/O functions with the custom ones.
+
+ @param in_func: input function similar to standard raw_input
+ @type in_func: str -> str
+ @param out_func: output function similar to standard print
+ @type out_func: str -> None
+
+ """
+
+ self.in_func = in_func
+ self.out_func = out_func
+
+ def print(self, msg=""):
+ self.out_func(msg)
+
+ def raw_input(self, prompt):
+ return self.in_func(prompt)
+
class TextWindow(object):
"""Helper class providing some common methods needed by all text windows."""
def __init__(self, title, *args, **kwargs):
+ self._io = kwargs.get("io_handler", IOHandler())
self._title = title
# XXX: I know this must be really hard for translators, but there is no
@@ -45,12 +77,12 @@ class TextWindow(object):
def _print_rule(self):
rule = self._usable_width * "="
- print rule
+ self._io.print(rule)
def print_header(self):
- print
+ self._io.print()
self._print_rule()
- print self._title
+ self._io.print(self._title)
self._print_rule()
def destroy(self):
@@ -61,6 +93,16 @@ class TextIntf(AbstractIntf):
def __init__(self, *args, **kwargs):
AbstractIntf.__init__(self, *args, **kwargs)
self.screen = kwargs.get("screen", None)
+ self._io = kwargs.get("io_handler", IOHandler())
+
+ def set_io_handler(self, handler):
+ """
+ Set different IO handler.
+
+ @type handler: an instance of the IOHandler class
+
+ """
+ self._io = handler
def enableNetwork(self, *args, **kwargs):
"""Should be provided by the inheriting class."""
@@ -68,20 +110,24 @@ class TextIntf(AbstractIntf):
return False
def exitWindow(self, title, message, *args, **kwargs):
+ kwargs["io_handler"] = self._io
win = ExitWindow(title, message, *args, **kwargs)
win.run()
win.destroy()
def mainExceptionWindow(self, text, exnFile, *args, **kwargs):
+ kwargs["io_handler"] = self._io
win = MainExceptionWindow(text, exnFile, *args, **kwargs)
return win
def messageWindow(self, title, message, *args, **kwargs):
+ kwargs["io_handler"] = self._io
win = MessageWindow(title, message, *args, **kwargs)
win.run()
win.destroy()
def saveExceptionWindow(self, signature, *args, **kwargs):
+ kwargs["io_handler"] = self._io
win = SaveExceptionWindow(signature, *args, **kwargs)
win.run()
win.destroy()
@@ -112,16 +158,16 @@ class MainExceptionWindow(TextWindow, AbstractMainExceptionWindow):
def run(self, *args, **kwargs):
self.print_header()
- print self._short_traceback
- print _("What do you want to do now?")
+ self._io.print(self._short_traceback)
+ self._io.print(_("What do you want to do now?"))
for (idx, item) in enumerate(self._menu_items):
- print "%d) %s" % (idx + 1, item[0])
+ self._io.print("%d) %s" % (idx + 1, item[0]))
ret = -1
num_menu_items = len(self._menu_items)
- print
+ self._io.print()
while not (0 < ret <= num_menu_items):
- ret = raw_input(_("Please make your choice from above: "))
+ ret = self._io.raw_input(_("Please make your choice from above: "))
try:
ret = int(ret)
except ValueError:
@@ -137,9 +183,9 @@ class MessageWindow(TextWindow, AbstractMessageWindow):
def run(self, *args, **kwargs):
self.print_header()
- print self._text
- print
- raw_input(_("Hit ENTER to continue"))
+ self._io.print(self._text)
+ self._io.print()
+ self._io.raw_input(_("Hit ENTER to continue"))
class ExitWindow(MessageWindow):
def __init__(self, title, text, *args, **kwargs):
@@ -147,14 +193,15 @@ class ExitWindow(MessageWindow):
def run(self, *args, **kwargs):
self.print_header()
- print self._text
- print
+ self._io.print(self._text)
+ self._io.print()
# self._no_answer may be non-ascii string (simple .upper() doesn't work)
no_answer_upper = self._no_answer.decode("utf-8").upper().encode("utf-8")
- answer = raw_input(_("Are you sure you want to exit? [%(yes)s/%(no)s]") %
- { "yes": self._yes_answer,
- "no": no_answer_upper })
+ answer = self._io.raw_input(_(
+ "Are you sure you want to exit? [%(yes)s/%(no)s]") %
+ { "yes": self._yes_answer,
+ "no": no_answer_upper })
# no answer means accepting the default (self._no_answer) and the answer
# is case insensitive (and may be non-ascii)
--
1.7.11.7
More information about the anaconda-patches
mailing list