[PATCH 1/2] Refactor and cleanup exception handling pieces

Vratislav Podzimek vpodzime at redhat.com
Thu Jan 17 12:17:21 UTC 2013


Before this patch our UserInterface classes somehow "implicitly"
inherited python-meh's *Intf classes by providing two methods with right
names. This patch adds a meh_interface property to our UserInterface
classes that returns an instance of a class that really is inherited
from the python-meh's *Intf class or actually is an instance of the
python-meh's *Intf class in case of gui and tui respectively. It also
adds a tty_num property to our *UserInterface classes that can be used
in runDebug to get user to the right console before and after the pdb
session automatically.

Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
---
 pyanaconda/exception.py       | 24 +++++++++----
 pyanaconda/ui/__init__.py     | 26 +++++++-------
 pyanaconda/ui/gui/__init__.py | 83 +++++++++++++++++++++++++++++--------------
 pyanaconda/ui/tui/__init__.py | 19 +++++-----
 4 files changed, 99 insertions(+), 53 deletions(-)

diff --git a/pyanaconda/exception.py b/pyanaconda/exception.py
index 09f9837..2c852ae 100644
--- a/pyanaconda/exception.py
+++ b/pyanaconda/exception.py
@@ -43,6 +43,17 @@ _ = lambda x: gettext.ldgettext("anaconda", x)
 
 
 class AnacondaExceptionHandler(ExceptionHandler):
+
+    def __init__(self, confObj, intfClass, exnClass, tty_num):
+        """
+        @see: python-meh's ExceptionHandler
+        @param tty_num: the number of tty the interface is running on
+
+        """
+
+        ExceptionHandler.__init__(self, confObj, intfClass, exnClass)
+        self._intf_tty_num = tty_num
+
     def handleException(self, (ty, value, tb), obj):
 
         def run_handleException_on_idle(args_tuple):
@@ -60,7 +71,7 @@ class AnacondaExceptionHandler(ExceptionHandler):
             super(AnacondaExceptionHandler, self).handleException((ty, value, tb),
                                                                   obj)
             return False
-            
+
         if issubclass(ty, storage.errors.StorageError) and value.hardware_fault:
             hw_error_msg = _("The installation was stopped due to what "
                              "seems to be a problem with your hardware. "
@@ -105,9 +116,8 @@ class AnacondaExceptionHandler(ExceptionHandler):
             pass
 
     def runDebug(self, (ty, value, tb)):
-        # vtActivate does not work on certain ppc64 machines, so just skip
-        # that and continue with the rest of the debugger setup.
-        iutil.vtActivate(1)
+        if self._intf_tty_num != 1:
+            iutil.vtActivate(1)
 
         pidfl = "/tmp/vncshell.pid"
         if os.path.exists(pidfl) and os.path.isfile(pidfl):
@@ -137,7 +147,8 @@ class AnacondaExceptionHandler(ExceptionHandler):
         import pdb
         pdb.post_mortem (tb)
 
-        iutil.vtActivate(6)
+        if self._intf_tty_num != 1:
+            iutil.vtActivate(self._intf_tty_num)
 
 def initExceptionHandling(anaconda):
     fileList = [ "/tmp/anaconda.log", "/tmp/packaging.log",
@@ -164,7 +175,8 @@ def initExceptionHandling(anaconda):
                                 "payload._yum"],
                   localSkipList=[ "passphrase", "password" ],
                   fileList=fileList)
-    handler = AnacondaExceptionHandler(conf, anaconda.intf, ReverseExceptionDump)
+    handler = AnacondaExceptionHandler(conf, anaconda.intf.meh_interface,
+                                       ReverseExceptionDump, anaconda.intf.tty_num)
     handler.install(anaconda)
 
     return conf
diff --git a/pyanaconda/ui/__init__.py b/pyanaconda/ui/__init__.py
index 9337a2a..d09e9b4 100644
--- a/pyanaconda/ui/__init__.py
+++ b/pyanaconda/ui/__init__.py
@@ -64,6 +64,11 @@ class UserInterface(object):
     basemask = "pyanaconda.ui"
     paths = PathDict({})
 
+    @property
+    def tty_num(self):
+        """Returns the number of tty the UserInterface is running on."""
+        raise NotImplementedError
+
     @classmethod
     def update_paths(cls, pathdict):
         """Receives pathdict and appends it's contents to the current
@@ -85,6 +90,15 @@ class UserInterface(object):
         """
         raise NotImplementedError
 
+    @property
+    def meh_interface(self):
+        """
+        Returns an interface for exception handling (defined by python-meh's
+        AbstractIntf class).
+
+        """
+        raise NotImplementedError
+
     ###
     ### MESSAGE HANDLING METHODS
     ###
@@ -156,15 +170,3 @@ class UserInterface(object):
                                         key=lambda obj: obj.priority))
 
         return actionClasses
-
-    def mainExceptionWindow(self, text, exn_file):
-        """Return window with the exception and buttons for debugging, bug
-           reporting and exitting the installer.
-
-           This method will be called only when unhandled exception appears.
-        """
-        raise NotImplementedError
-
-    def saveExceptionWindow(self, account_manager, signature):
-        """Show a window that provides a way to report a bug."""
-        raise NotImplementedError
diff --git a/pyanaconda/ui/gui/__init__.py b/pyanaconda/ui/gui/__init__.py
index a7c9ea7..73925e7 100644
--- a/pyanaconda/ui/gui/__init__.py
+++ b/pyanaconda/ui/gui/__init__.py
@@ -230,7 +230,9 @@ class GraphicalUserInterface(UserInterface):
         self._distributionText = distributionText
         self._isFinal = isFinal
         self._quitDialog = quitDialog
-    
+        self._mehInterface = GraphicalExceptionHandlingIface(
+                                    self.lightbox_over_current_action)
+
         # This is a hack to make sure the AnacondaWidgets library gets loaded
         # before glade tries to use Anaconda types
         # glade file should contain the following line to make this seamless
@@ -259,7 +261,15 @@ class GraphicalUserInterface(UserInterface):
                       os.path.join(path, "hubs"))
                       for path in pathlist]
             }
-        
+
+    @property
+    def tty_num(self):
+        return 6
+
+    @property
+    def meh_interface(self):
+        return self._mehInterface
+
     def _list_hubs(self):
         """Return a list of Hub classes to be imported to this interface"""
         from .hubs.summary import SummaryHub
@@ -289,6 +299,20 @@ class GraphicalUserInterface(UserInterface):
         # Second, order them according to their relationship
         return self._orderActionClasses(standalones, hubs)
 
+    def lightbox_over_current_action(self, window):
+        """
+        Creates lightbox over current action for the given window. Or
+        DOES NOTHING IF THERE ARE NO ACTIONS.
+
+        """
+
+        from gi.repository import AnacondaWidgets
+
+        # if there are no actions (not populated yet), we can do nothing
+        if len(self._actions) > 0:
+            lightbox = AnacondaWidgets.lb_show_over(self._currentAction.window)
+            window.main_window.set_transient_for(lightbox)
+
     def _instantiateAction(self, actionClass):
         from spokes import StandaloneSpoke
 
@@ -399,30 +423,6 @@ class GraphicalUserInterface(UserInterface):
 
         return bool(rc)
 
-
-    def mainExceptionWindow(self, text, exn_file, *args, **kwargs):
-        from gi.repository import Gtk, AnacondaWidgets
-
-        meh_intf = meh.ui.gui.GraphicalIntf()
-        exc_window = meh_intf.mainExceptionWindow(text, exn_file)
-        exc_window.main_window.set_decorated(False)
-
-        # exception may appear before self._actions gets populated
-        if len(self._actions) > 0:
-            lightbox = AnacondaWidgets.lb_show_over(self._currentAction.window)
-            exc_window.main_window.set_transient_for(lightbox)
-
-        # without WindowGroup, python-meh's window is insensitive if it appears
-        # above a spoke (Gtk.Window running its own Gtk.main loop)
-        window_group = Gtk.WindowGroup()
-        window_group.add_window(exc_window.main_window)
-
-        return exc_window
-
-    def saveExceptionWindow(self, signature, *args, **kwargs):
-        meh_intf = meh.ui.gui.GraphicalIntf()
-        meh_intf.saveExceptionWindow(signature)
-
     ###
     ### SIGNAL HANDLING METHODS
     ###
@@ -493,7 +493,38 @@ class GraphicalUserInterface(UserInterface):
         if rc == 1:
             sys.exit(0)
 
+class GraphicalExceptionHandlingIface(meh.ui.gui.GraphicalIntf):
+    """
+    Class inheriting from python-meh's GraphicalIntf and overriding methods
+    that need some modification in Anaconda.
+
+    """
+
+    def __init__(self, lightbox_func):
+        """
+        @param lightbox_func: a function that creates lightbox for a given
+                              window
+        @type lightbox_func: GtkWindow -> None
+
+        """
+
+        self._lightbox_func = lightbox_func
 
+    def mainExceptionWindow(self, text, exn_file, *args, **kwargs):
+        from gi.repository import Gtk
+
+        meh_intf = meh.ui.gui.GraphicalIntf()
+        exc_window = meh_intf.mainExceptionWindow(text, exn_file)
+        exc_window.main_window.set_decorated(False)
+
+        self._lightbox_func(exc_window)
+
+        # without WindowGroup, python-meh's window is insensitive if it appears
+        # above a spoke (Gtk.Window running its own Gtk.main loop)
+        window_group = Gtk.WindowGroup()
+        window_group.add_window(exc_window.main_window)
+
+        return exc_window
 
 def busyCursor():
     window = Gdk.get_default_root_window()
diff --git a/pyanaconda/ui/tui/__init__.py b/pyanaconda/ui/tui/__init__.py
index cebb6c4..64b9f7f 100644
--- a/pyanaconda/ui/tui/__init__.py
+++ b/pyanaconda/ui/tui/__init__.py
@@ -130,6 +130,7 @@ class TextUserInterface(ui.UserInterface):
 
         ui.UserInterface.__init__(self, storage, payload, instclass)
         self._app = None
+        self._meh_interface = meh.ui.text.TextIntf()
 
     basemask = "pyanaconda.ui.tui"
     basepath = os.path.dirname(__file__)
@@ -146,7 +147,15 @@ class TextUserInterface(ui.UserInterface):
                       os.path.join(path, "hubs"))
                       for path in pathlist]
             }
-    
+
+    @property
+    def tty_num(self):
+        return 1
+
+    @property
+    def meh_interface(self):
+        return self._meh_interface
+
     def _list_hubs(self):
         """returns the list of hubs to use"""
         return [SummaryHub, ProgressHub]
@@ -225,11 +234,3 @@ class TextUserInterface(ui.UserInterface):
         question_window = YesNoDialog(self._app, message)
         self._app.switch_screen_modal(question_window)
         return question_window.answer
-
-    def mainExceptionWindow(self, text, exn_file, *args, **kwargs):
-        meh_intf = meh.ui.text.TextIntf()
-        return meh_intf.mainExceptionWindow(text, exn_file, *args, **kwargs)
-
-    def saveExceptionWindow(self, signature, *args, **kwargs):
-        meh_intf = meh.ui.text.TextIntf()
-        return meh_intf.saveExceptionWindow(signature, *args, **kwargs)
-- 
1.7.11.7



More information about the anaconda-patches mailing list