Using ExceptionInfo and DumpInfo named tuples makes code clearer and
simplifies documentation.
Signed-off-by: Vratislav Podzimek <vpodzime(a)redhat.com>
---
meh/__init__.py | 8 ++++++++
meh/dump.py | 24 ++++++++++++------------
meh/handler.py | 54 +++++++++++++++++++++++++++---------------------------
po/python-meh.pot | 2 +-
tests/baseclass.py | 3 ++-
5 files changed, 50 insertions(+), 41 deletions(-)
diff --git a/meh/__init__.py b/meh/__init__.py
index 329969f..d09a131 100644
--- a/meh/__init__.py
+++ b/meh/__init__.py
@@ -20,6 +20,8 @@
# Author(s): Chris Lumens <clumens(a)redhat.com>
#
+from collections import namedtuple
+
# These constants represent the return values of buttons on the initial
# exception handling dialog - the dialog that first pops up when an
# exception is hit.
@@ -127,3 +129,9 @@ class Config(object):
else:
msg = "Callback with name '%s' already registered" %
item_name
raise ConfigError(msg)
+
+# type, value and stack are items provided by Python for the exception handler
+ExceptionInfo = namedtuple("ExceptionInfo", ["type",
"value", "stack"])
+
+# ExceptionInfo instance plus the object that should be dumped
+DumpInfo = namedtuple("DumpInfo", ["exc_info", "object"])
diff --git a/meh/dump.py b/meh/dump.py
index c868aa4..4639327 100644
--- a/meh/dump.py
+++ b/meh/dump.py
@@ -35,23 +35,23 @@ class ExceptionDump(object):
for manipulating a traceback. In general, clients should not have to
use this class. It is mainly for internal use.
"""
- def __init__(self, (ty, value, stack), configObj):
+ def __init__(self, exc_info, config_obj):
"""Create a new ExceptionDump instance. Instance attributes:
- (type, value, stack) -- These are the values provided by python
- when an exception is generated, and are
- what ExceptionDump wraps to make more
- useful.
- conf -- An instance of the Config object.
+ @param exc_info: info about the exception provided by Python
+ @type exc_info: an instance of the meh.ExceptionInfo class
+ @param config_obj: configuration for python-meh
+ @type config_obj: an instance of the meh.Config class
"""
- if inspect.istraceback(stack):
- stack = inspect.getinnerframes(stack)
+ if inspect.istraceback(exc_info.stack):
+ self.stack = inspect.getinnerframes(exc_info.stack)
+ else:
+ self.stack = exc_info.stack
- self.conf = configObj
- self.stack = stack
- self.type = ty
- self.value = value
+ self.conf = config_obj
+ self.type = exc_info.type
+ self.value = exc_info.value
self._dumpHash = {}
diff --git a/meh/handler.py b/meh/handler.py
index 6338cf2..6427656 100644
--- a/meh/handler.py
+++ b/meh/handler.py
@@ -68,7 +68,7 @@ class ExceptionHandler(object):
exn = property(lambda s: s._exn,
lambda s, v: s._setExn(v))
- def handleException(self, (ty, value, tb), obj):
+ def handleException(self, dump_info):
"""This is the main exception handling entry point. When Python
gets an exception it doesn't know how to handle, this method will
be called. It then saves the traceback and displays the main
@@ -79,6 +79,9 @@ class ExceptionHandler(object):
All arguments are passed in from the handler created by calling
self.install(). This method should not usually be overridden by
a subclass.
+
+ @type dump_info: an instance of the meh.DumpInfo class
+
"""
responseHash = {MAIN_RESPONSE_QUIT: self.runQuit,
@@ -86,34 +89,34 @@ class ExceptionHandler(object):
MAIN_RESPONSE_SAVE: self.runSave}
# Quit if we got an exception when running pdb.
- if isinstance(value, bdb.BdbQuit):
+ if isinstance(dump_info.exc_info.value, bdb.BdbQuit):
sys.exit(self.exitcode)
# Restore original exception handler.
sys.excepthook = sys.__excepthook__
- self.preWriteHook((ty, value, tb), obj)
+ self.preWriteHook(dump_info)
# Save the exception to the filesystem first.
- self.exn = self.exnClass((ty, value, tb), self.conf)
+ self.exn = self.exnClass(dump_info.exc_info, self.conf)
(fobj, self.exnFile) = self.openFile()
- self.exnText = self.exn.traceback_and_object_dump(obj)
+ self.exnText = self.exn.traceback_and_object_dump(dump_info.object)
fobj.write(self.exnText)
fobj.close()
- self.postWriteHook((ty, value, tb), obj)
+ self.postWriteHook(dump_info)
# Run initial UI screen, asking whether to save/debug/quit.
while True:
win = self.intf.mainExceptionWindow(str(self.exn), self.exnText)
if not win:
- self.runQuit((ty, value, tb))
+ self.runQuit(dump_info.exc_info)
rc = win.run()
win.destroy()
try:
- responseHash[rc]((ty, value, tb))
+ responseHash[rc](dump_info.exc_info)
except KeyError:
# This happens if (for example) the user hits Escape instead
# of pressing a button.
@@ -121,33 +124,23 @@ class ExceptionHandler(object):
win.destroy()
- def preWriteHook(self, (ty, value, tb), obj):
+ def preWriteHook(self, dump_info):
"""Subclasses may supply a function with this name that will be
called immediately before the traceback is written to disk in
order to have any sort of special pre-write processing that needs
to be done.
- (ty, value, tb) -- The Python objects created when a traceback
- occurs. These are passed in directly from
- handleException.
- obj -- A Python object that may be dumped to a file when the
- exception is saved. This should be something like the top
- level object in a program.
+ @type dump_info: an instance of the meh.DumpInfo class
"""
pass
- def postWriteHook(self, (ty, value, tb), obj):
+ def postWriteHook(self, dump_info):
"""Subclasses may supply a function with this name that will be
called immediately after the traceback is written to disk, but
immediately before the UI is run. This is to provide a place for
any special handling to happen once there is a file on disk.
- (ty, value, tb) -- The Python objects created when a traceback
- occurs. These are passed in directly from
- handleException.
- obj -- A Python object that may be dumped to a file when the
- exception is saved. This should be something like the top
- level object in a program.
+ @type dump_info: an instance of the meh.DumpInfo class
"""
pass
@@ -160,7 +153,8 @@ class ExceptionHandler(object):
exception is saved. This should be something like the top
level object in a program.
"""
- sys.excepthook = lambda ty, value, tb: self.handleException((ty, value, tb),
obj)
+ sys.excepthook = lambda ty, value, tb: \
+ self.handleException(DumpInfo(ExceptionInfo(ty, value, tb), obj))
def openFile(self):
"""Create a randomly named output file to write the exception dump
to.
@@ -176,29 +170,35 @@ class ExceptionHandler(object):
### Methods called by the primary exception handling dialog.
- def runQuit(self, (ty, value, tb)):
+ def runQuit(self, exc_info):
"""This method is called when the "Exit" button is
clicked. It may
be overridden by a subclass, but the basic behavior of eventually
quitting should be preserved.
+
+ @type exc_info: an instance of the meh.ExceptionInfo class
"""
sys.exit(self.exitcode)
- def runDebug(self, (ty, value, tb)):
+ def runDebug(self, exc_info):
"""This method is called when the "Debug" button is
clicked. It may
be overridden by a subclass if specialized behavior is required to
enter debug mode.
+
+ @type exc_info: an instance of the meh.ExceptionInfo class
"""
print
print "Use 'continue' command to quit the debugger and get back to
"\
"the main menu"
import pdb
- pdb.post_mortem(tb)
+ pdb.post_mortem(exc_info.stack)
#no need to quit here, let's just get back to the main dialog
- def runSave(self, (ty, value, tb)):
+ def runSave(self, exc_info):
"""This method is called when the "Save" button is
clicked. It may
be overridden by a subclass, but that's going to be a lot of work.
+
+ @type exc_info: an instance of the meh.ExceptionInfo class
"""
params = dict()
diff --git a/po/python-meh.pot b/po/python-meh.pot
index 44395da..5d4f33f 100644
--- a/po/python-meh.pot
+++ b/po/python-meh.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-01-21 12:43+0100\n"
+"POT-Creation-Date: 2013-03-05 12:14+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL(a)li.org>\n"
diff --git a/tests/baseclass.py b/tests/baseclass.py
index a0173b7..befa9b4 100644
--- a/tests/baseclass.py
+++ b/tests/baseclass.py
@@ -5,6 +5,7 @@ import sys
import tempfile
import unittest
+from meh import ExceptionInfo
from meh.handler import *
from meh.dump import *
@@ -13,7 +14,7 @@ class BaseTestCase(unittest.TestCase):
from inspect import stack as _stack
stack = _stack()[1:]
- dump = ExceptionDump((None, None, stack), conf)
+ dump = ExceptionDump(ExceptionInfo(None, None, stack), conf)
return dump.dump(obj)
def openFile(self):
--
1.7.11.7